Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ The **[WAMR SDK](./wamr-sdk)** tools is helpful to finish the two tasks quickly.
Samples
=================

The WAMR [samples](./samples) integrate the iwasm VM core, application manager and selected application framework components.
The WAMR [samples](./samples) integrate the iwasm VM core, application manager and selected application framework components.

- [**Basic**](./samples/basic): Demonstrating how host runtime calls WASM function as well as WASM function calls native function.
- **[Simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default.
- **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LittlevGL](https://github.com/littlevgl/) 2D user graphic library and the UI application is built into WASM application. It uses **WASI libc** and executes apps in **AoT mode** by default.
- **[gui](./samples/gui/README.md)**: Moved the [LittlevGL](https://github.com/littlevgl/) library into the runtime and defined a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default.
Expand Down
10 changes: 5 additions & 5 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1821,11 +1821,11 @@ typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64*,uint64);
typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64*, uint64);
typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64*, uint64);

static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative;
static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative;
static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)(uintptr_t)invokeNative;
static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative;
static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;

#if defined(_WIN32) || defined(_WIN32_)
#define MAX_REG_FLOATS 4
Expand Down
42 changes: 42 additions & 0 deletions samples/basic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required (VERSION 2.8)

project (basic)

################ runtime settings ################
set (WAMR_BUILD_PLATFORM "linux")

# Reset default linker flags
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")

# WAMR features switch
set (WAMR_BUILD_TARGET "X86_64")
set(CMAKE_BUILD_TYPE Debug)
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_LIBC_BUILTIN 1)
set (WAMR_BUILD_LIBC_WASI 1)
set (WAMR_BUILD_FAST_INTERP 0)

# linker flags
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")

# build out vmlib
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)

add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})

################ application related ################
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)

add_executable (basic src/main.c src/native_impl.c ${UNCOMMON_SHARED_SOURCE})

target_link_libraries (basic vmlib -lm -ldl -lpthread -lrt)
51 changes: 51 additions & 0 deletions samples/basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@


The "basic" sample project
==============

This sample demonstrates a few basic usages of embedding WAMR:
- initialize runtime
- load wasm app and instantiate the module
- call wasm function and pass arguments
- export native functions to the WASM apps
- wasm function calls native function and pass arguments
- deinitialize runtime

Build this sample
==============
Execute the ```build.sh``` script then all binaries including wasm application files would be generated in 'out' directory.

```
$ ./build.sh
```

Run the sample
==========================
Enter the out directory.
```
$ cd ./out/
$
$ ./basic wasm-apps/testapp.wasm
calling into WASM function: generate_float
Native finished calling wasm function generate_float(), returned a float value: 102009.921875f
calling into WASM function: float_to_string
calling into native function: intToStr
calling into native function: get_pow
calling into native function: intToStr
Native finished calling wasm function: float_to_string, returned a formatted string: 102009.921
```
Or execute the ```run.sh``` script in ```samples/basic``` folder.
```
$ ./run.sh
calling into WASM function: generate_float
Native finished calling wasm function generate_float(), returned a float value: 102009.921875f
calling into WASM function: float_to_string
calling into native function: intToStr
calling into native function: get_pow
calling into native function: intToStr
Native finished calling wasm function: float_to_string, returned a formatted string: 102009.921
```




57 changes: 57 additions & 0 deletions samples/basic/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

CURR_DIR=$PWD
WAMR_DIR=${PWD}/../..
OUT_DIR=${PWD}/out

WASM_APPS=${PWD}/wasm-apps


rm -rf ${OUT_DIR}
mkdir ${OUT_DIR}
mkdir ${OUT_DIR}/wasm-apps


echo "#####################build basic project"
cd ${CURR_DIR}
mkdir -p cmake_build
cd cmake_build
cmake ..
make
if [ $? != 0 ];then
echo "BUILD_FAIL basic exit as $?\n"
exit 2
fi

cp -a basic ${OUT_DIR}

echo -e "\n"

echo "#####################build wasm apps"

cd ${WASM_APPS}

for i in `ls *.c`
do
APP_SRC="$i"
OUT_FILE=${i%.*}.wasm

# use WAMR SDK to build out the .wasm binary
/opt/wasi-sdk/bin/clang \
--target=wasm32 -O0 -z stack-size=4096 -Wl,--initial-memory=65536 \
--sysroot=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot \
-Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt \
-Wl,--no-threads,--strip-all,--no-entry -nostdlib \
-Wl,--export=generate_float \
-Wl,--export=float_to_string \
-Wl,--allow-undefined \
-o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC}


if [ -f ${OUT_DIR}/wasm-apps/${OUT_FILE} ]; then
echo "build ${OUT_FILE} success"
else
echo "build ${OUT_FILE} fail"
fi
done
echo "####################build wasm apps done"
3 changes: 3 additions & 0 deletions samples/basic/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

out/basic -f out/wasm-apps/testapp.wasm
178 changes: 178 additions & 0 deletions samples/basic/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@

/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#include "wasm_export.h"
#include "bh_read_file.h"

int intToStr(int x, char* str, int str_len, int digit);
int get_pow(int x, int y);

void print_usage(void)
{
fprintf(stdout, "Options:\r\n");
fprintf(stdout, " -f [path of wasm file] \n");
}


int main(int argc, char *argv_main[])
{
static char global_heap_buf[512 * 1024];
char *buffer, error_buf[128];
int opt;
char * wasm_path;

wasm_module_t module = NULL;
wasm_module_inst_t module_inst = NULL;
wasm_exec_env_t exec_env = NULL;
uint32 buf_size, stack_size = 8092, heap_size = 8092;
wasm_function_inst_t func = NULL;
wasm_function_inst_t func2 = NULL;
char * native_buffer = NULL;
int32_t wasm_buffer = 0;

RuntimeInitArgs init_args;
memset(&init_args, 0, sizeof(RuntimeInitArgs));

while ((opt = getopt(argc, argv_main, "hf:")) != -1)
{
switch (opt)
{
case 'f':
wasm_path = optarg;
break;
case 'h':
print_usage();
return 0;
case '?':
print_usage();
return 0;
}
}
if (optind == 1) {
print_usage();
return 0;
}

// Define an array of NativeSymbol for the APIs to be exported.
// Note: the array must be static defined since runtime
// will keep it after registration
// For the function signature specifications, goto the link:
// https://github.com/bytecodealliance/wasm-micro-runtime/blob/master/doc/export_native_api.md

static NativeSymbol native_symbols[] =
{
{
"intToStr", // the name of WASM function name
intToStr, // the native function pointer
"(i*~i)i" // the function prototype signature, avoid to use i32
},
{
"get_pow", // the name of WASM function name
get_pow, // the native function pointer
"(ii)i" // the function prototype signature, avoid to use i32
}
};

init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);

// Native symbols need below registration phase
init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
init_args.native_module_name = "env";
init_args.native_symbols = native_symbols;

if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime environment failed.\n");
return -1;
}

buffer = bh_read_file_to_buffer(wasm_path, &buf_size);

if(!buffer) {
printf("Open wasm app file [%s] failed.\n", wasm_path);
goto fail;
}

module = wasm_runtime_load(buffer, buf_size, error_buf, sizeof(error_buf));
if(!module) {
printf("Load wasm module failed. error: %s\n", error_buf);
goto fail;
}

module_inst = wasm_runtime_instantiate(module,
stack_size,
heap_size,
error_buf,
sizeof(error_buf));

if(!module_inst) {
printf("Instantiate wasm module failed. error: %s\n", error_buf);
goto fail;
}

exec_env = wasm_runtime_create_exec_env(module_inst, stack_size);
if(!exec_env) {
printf("Create wasm execution environment failed.\n");
goto fail;
}

uint32 argv[4];
double arg_d = 0.000101;
argv[0] = 10;
// the second arg will occupy two array elements
memcpy(&argv[1], &arg_d, sizeof(arg_d));
*(float*)(argv+3) = 300.002;

if(!(func = wasm_runtime_lookup_function(module_inst, "generate_float", NULL))){
printf("The generate_float wasm function is not found.\n");
goto fail;
}

// pass 4 elements for function arguments
if (!wasm_runtime_call_wasm(exec_env, func, 4, argv) ) {
printf("call wasm function generate_float failed. %s\n", wasm_runtime_get_exception(module_inst));
goto fail;
}

float ret_val = *(float*)argv;
printf("Native finished calling wasm function generate_float(), returned a float value: %ff\n", ret_val );

// Next we will pass a buffer to the WASM function
uint32 argv2[4];

// must allocate buffer from wasm instance memory space (never use pointer from host runtime)
wasm_buffer = wasm_runtime_module_malloc(module_inst, 100, (void**)&native_buffer);

*(float*)argv2 = ret_val; // the first argument
argv2[1] = wasm_buffer; // the second argument is the wasm buffer address
argv2[2] = 100; // the third argument is the wasm buffer size
argv2[3] = 3; // the last argument is the digits after decimal point for converting float to string

if(!(func2 = wasm_runtime_lookup_function(module_inst, "float_to_string", NULL))){
printf("The wasm function float_to_string wasm function is not found.\n");
goto fail;
}

if (wasm_runtime_call_wasm(exec_env, func2, 4, argv2) ) {
printf("Native finished calling wasm function: float_to_string, returned a formatted string: %s\n", native_buffer);
}
else {
printf("call wasm function float_to_string failed. error: %s\n", wasm_runtime_get_exception(module_inst));
goto fail;
}

fail:
if(exec_env) wasm_runtime_destroy_exec_env(exec_env);
if(module_inst) {
if(wasm_buffer) wasm_runtime_module_free(module_inst, wasm_buffer);
wasm_runtime_deinstantiate(module_inst);
}
if(module) wasm_runtime_unload(module);
if(buffer) BH_FREE(buffer);
wasm_runtime_destroy();
return 0;
}
Loading