diff --git a/samples/native-lib/CMakeLists.txt b/samples/native-lib/CMakeLists.txt index b6665c2cf..cb4a6f40b 100644 --- a/samples/native-lib/CMakeLists.txt +++ b/samples/native-lib/CMakeLists.txt @@ -58,7 +58,9 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) -add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) +# Note: we build vmlib as a shared library here so that it can be +# shared between iwasm and native libraries. +add_library(vmlib SHARED ${WAMR_RUNTIME_LIB_SOURCE}) ################ wamr runtime ################### include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) @@ -79,6 +81,10 @@ target_link_libraries(iwasm vmlib -lpthread -lm -ldl) add_library (test_add SHARED test_add.c) add_library (test_sqrt SHARED test_sqrt.c) add_library (test_hello SHARED test_hello.c) +# Note: Unlike simpler examples above, test_hello2 directly uses +# the API provided by the vmlib library. +add_library (test_hello2 SHARED test_hello2.c) +target_link_libraries(test_hello2 vmlib) ################ wasm application ############### add_subdirectory(wasm-app) diff --git a/samples/native-lib/README.md b/samples/native-lib/README.md index d5b50a716..2bf65814d 100644 --- a/samples/native-lib/README.md +++ b/samples/native-lib/README.md @@ -49,14 +49,14 @@ will be generated. ```bash cd build -./iwasm --native-lib=./libtest_add.so --native-lib=./libtest_sqrt.so --native-lib=./libtest_hello.so wasm-app/test.wasm +./iwasm --native-lib=./libtest_add.so --native-lib=./libtest_sqrt.so --native-lib=./libtest_hello.so --native-lib=./libtest_hello2.so wasm-app/test.wasm ``` ### macOS ```bash cd build -./iwasm --native-lib=libtest_add.dylib --native-lib=libtest_sqrt.dylib --native-lib=libtest_hello.dylib wasm-app/test.wasm +./iwasm --native-lib=libtest_add.dylib --native-lib=libtest_sqrt.dylib --native-lib=libtest_hello.dylib --native-lib=libtest_hello2.dylib wasm-app/test.wasm ``` The output is: @@ -66,7 +66,11 @@ Hello World! 10 + 20 = 30 sqrt(10, 20) = 500 test_hello("main", 0x0, 0) = 41 -malloc(42) = 0x24b8 -test_hello("main", 0x24b8, 42) = 41 +malloc(42) = 0x24e8 +test_hello("main", 0x24e8, 42) = 41 Message from test_hello: Hello, main. This is test_hello_wrapper! +test_hello2("main", 0x0, 0) = 85 +malloc(86) = 0x24e8 +test_hello2("main", 0x24e8, 86) = 85 +Message from test_hello2: Hello, main. This is test_hello2_wrapper! Your wasm_module_inst_t is 0x7fd443704990. ``` diff --git a/samples/native-lib/test_hello2.c b/samples/native-lib/test_hello2.c new file mode 100644 index 000000000..2c8f69ed6 --- /dev/null +++ b/samples/native-lib/test_hello2.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +/* + * This example basically does the same thing as test_hello.c, + * using wasm_export.h API. + */ + +#include +#include + +#include "wasm_export.h" + +static int +test_hello2_wrapper(wasm_exec_env_t exec_env, uint32_t nameaddr, + uint32_t resultaddr, uint32_t resultlen) +{ + /* + * Perform wasm_runtime_malloc to check if the runtime has been + * initialized as expected. + * This would fail with "memory hasn't been initialize" error + * unless we are not sharing a runtime with the loader app. (iwasm) + */ + void *p = wasm_runtime_malloc(1); + if (p == NULL) { + return -1; + } + wasm_runtime_free(p); + + wasm_module_inst_t inst = wasm_runtime_get_module_inst(exec_env); + if (!wasm_runtime_validate_app_str_addr(inst, nameaddr) + || !wasm_runtime_validate_app_addr(inst, resultaddr, resultlen)) { + return -1; + } + const char *name = wasm_runtime_addr_app_to_native(inst, nameaddr); + char *result = wasm_runtime_addr_app_to_native(inst, resultaddr); + return snprintf(result, resultlen, + "Hello, %s. This is %s! Your wasm_module_inst_t is %p.\n", + name, __func__, inst); +} + +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } + +static NativeSymbol native_symbols[] = { + REG_NATIVE_FUNC(test_hello2, "(iii)i") +}; +/* clang-format on */ + +uint32_t +get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols) +{ + *p_module_name = "env"; + *p_native_symbols = native_symbols; + return sizeof(native_symbols) / sizeof(NativeSymbol); +} diff --git a/samples/native-lib/wasm-app/main.c b/samples/native-lib/wasm-app/main.c index 09b283789..dba652daf 100644 --- a/samples/native-lib/wasm-app/main.c +++ b/samples/native-lib/wasm-app/main.c @@ -15,6 +15,9 @@ test_sqrt(int x, int y); int test_hello(const char *name, char *buf, size_t buflen); +int +test_hello2(const char *name, char *buf, size_t buflen); + int main(int argc, char **argv) { @@ -33,12 +36,35 @@ main(int argc, char **argv) res = test_hello(name, NULL, 0); printf("test_hello(\"%s\", %p, %zu) = %d\n", name, NULL, (size_t)0, res); + if (res == -1) { + return -1; + } buflen = res + 1; buf = malloc(buflen); printf("malloc(%zu) = %p\n", buflen, buf); res = test_hello(__func__, buf, buflen); + if (res == -1) { + return -1; + } printf("test_hello(\"%s\", %p, %zu) = %d\n", name, buf, buflen, res); printf("Message from test_hello: %s", buf); + free(buf); + + res = test_hello2(name, NULL, 0); + printf("test_hello2(\"%s\", %p, %zu) = %d\n", name, NULL, (size_t)0, res); + if (res == -1) { + return -1; + } + buflen = res + 1; + buf = malloc(buflen); + printf("malloc(%zu) = %p\n", buflen, buf); + res = test_hello2(__func__, buf, buflen); + if (res == -1) { + return -1; + } + printf("test_hello2(\"%s\", %p, %zu) = %d\n", name, buf, buflen, res); + printf("Message from test_hello2: %s", buf); + free(buf); return 0; }