summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/.gitignore2
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/CMakeLists.txt174
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/README.md174
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/CMakeLists.txt12
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/example1.c204
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/CMakeLists.txt47
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/inc/.gitkeep0
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/send_recv.c244
8 files changed, 857 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/.gitignore b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/.gitignore
new file mode 100644
index 000000000..ab998a6eb
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/.gitignore
@@ -0,0 +1,2 @@
+/wasm/inc/**
+!/wasm/inc/.*
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/CMakeLists.txt b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/CMakeLists.txt
new file mode 100644
index 000000000..1325e110c
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/CMakeLists.txt
@@ -0,0 +1,174 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required(VERSION 3.14)
+project(how-to-deal-with-import)
+
+include(CMakePrintHelpers)
+include(CTest)
+include(ExternalProject)
+include(FetchContent)
+
+#
+# dependencies
+#
+set(WAMR_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../)
+# wasm required headers
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${WARM_ROOT}/${WAMR_ROOT}/wamr-sdk/app/libc-builtin-sysroot/include/pthread.h
+ ${CMAKE_CURRENT_LIST_DIR}/wasm/inc
+)
+
+# vmlib
+################ runtime settings ################
+string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
+if (APPLE)
+ add_definitions(-DBH_PLATFORM_DARWIN)
+endif ()
+
+# Resetdefault linker flags
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# WAMR features switch
+
+# Set WAMR_BUILD_TARGET, currently values supported:
+# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
+# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
+if (NOT DEFINED WAMR_BUILD_TARGET)
+ if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
+ set (WAMR_BUILD_TARGET "AARCH64")
+ elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
+ set (WAMR_BUILD_TARGET "RISCV64")
+ elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ # Build as X86_64 by default in 64-bit platform
+ set (WAMR_BUILD_TARGET "X86_64")
+ elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
+ # Build as X86_32 by default in 32-bit platform
+ set (WAMR_BUILD_TARGET "X86_32")
+ else ()
+ message(SEND_ERROR "Unsupported build target platform!")
+ endif ()
+endif ()
+
+if (NOT CMAKE_BUILD_TYPE)
+ set (CMAKE_BUILD_TYPE Release)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_AOT)
+ # Enable AOT by default.
+ set (WAMR_BUILD_AOT 1)
+endif ()
+if (NOT DEFINED WAMR_BUILD_INTERP)
+ # Disable Interpreter by default
+ set (WAMR_BUILD_INTERP 0)
+endif ()
+set(WAMR_BUILD_JIT 0)
+set(WAMR_BUILD_FAST_INTERP 1)
+set(WAMR_BUILD_LIB_PTHREAD 1)
+set(WAMR_BUILD_LIBC_BUILTIN 1)
+set(WAMR_BUILD_LIBC_WASI 1)
+set(WAMR_BUILD_SIMD 0)
+
+# compiling and linking flags
+if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
+endif ()
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
+
+# 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})
+target_link_libraries(vmlib INTERFACE dl m pthread)
+if(WAMR_BUILD_AOT EQUAL 1)
+ target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_AOT=1)
+else()
+ target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_AOT=0)
+endif()
+
+if(WAMR_BUILD_INTERP EQUAL 1)
+ target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_INTERP=1)
+else()
+ target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_INTERP=0)
+endif()
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ # ASAN + UBSAN
+ target_compile_options(vmlib INTERFACE -fsanitize=address,undefined)
+ target_link_options(vmlib INTERFACE -fsanitize=address,undefined)
+endif()
+
+# # MSAN
+# target_compile_options(vmlib INTERFACE -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer)
+# target_link_options(vmlib INTERFACE -fsanitize=memory)
+
+# wamrc
+if(WAMR_BUILD_AOT EQUAL 1 AND WAMR_BUILD_INTERP EQUAL 0)
+ ExternalProject_Add(wamrc
+ PREFIX wamrc-build
+ SOURCE_DIR ${WAMR_ROOT}/wamr-compiler
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${WAMR_ROOT}/wamr-compiler -B build
+ BUILD_COMMAND ${CMAKE_COMMAND} --build build --target wamrc
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different build/wamrc ${CMAKE_CURRENT_BINARY_DIR}/wamrc
+ )
+endif()
+
+#
+# host
+add_subdirectory(host)
+add_custom_target(
+ install_host ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ./host/example1 .
+ DEPENDS example1
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# TODO: replace it with a find_package()
+set(WASI_SDK_DIR /opt/wasi-sdk-19.0/)
+set(WASI_TOOLCHAIN_FILE ${WASI_SDK_DIR}/share/cmake/wasi-sdk.cmake)
+set(WASI_SYS_ROOT ${WASI_SDK_DIR}/share/wasi-sysroot)
+
+#
+# wasm
+if(WAMR_BUILD_AOT EQUAL 1 AND WAMR_BUILD_INTERP EQUAL 0)
+ ExternalProject_Add(wasm
+ PREFIX wasm-build
+ DEPENDS wamrc
+ BUILD_ALWAYS TRUE
+ SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/wasm
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_LIST_DIR}/wasm -B build
+ -DWASI_SDK_PREFIX=${WASI_SDK_DIR}
+ -DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
+ -DCMAKE_SYSROOT=${WASI_SYS_ROOT}
+ -DWASM_TO_AOT=ON
+ -DWAMRC_PATH=${CMAKE_CURRENT_BINARY_DIR}/wamrc
+ -DSOCKET_WASI_CMAKE=${WAMR_ROOT}/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
+ BUILD_COMMAND ${CMAKE_COMMAND} --build build
+ INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
+ )
+else()
+ ExternalProject_Add(wasm
+ PREFIX wasm-build
+ BUILD_ALWAYS TRUE
+ SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/wasm
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_LIST_DIR}/wasm -B build
+ -DWASI_SDK_PREFIX=${WASI_SDK_DIR}
+ -DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
+ -DCMAKE_SYSROOT=${WASI_SYS_ROOT}
+ -DSOCKET_WASI_CMAKE=${WAMR_ROOT}/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
+ BUILD_COMMAND ${CMAKE_COMMAND} --build build
+ INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endif()
+
+#
+# Test
+#
+add_test(
+ NAME run_example1
+ COMMAND ./example1
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/README.md b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/README.md
new file mode 100644
index 000000000..9b61a6e74
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/README.md
@@ -0,0 +1,174 @@
+# How to create `imports` for wasm_instance_new() properly
+
+It's always been asked how to create `wasm_extern_vec_t *imports` for
+`wasm_instance_new()`?
+
+```c
+WASM_API_EXTERN own wasm_instance_t* wasm_instance_new(
+ wasm_store_t*, const wasm_module_t*, const wasm_extern_vec_t *imports,
+ own wasm_trap_t** trap
+);
+```
+
+`wasm_extern_vec_t *imports` is required to match the requirement of _the
+import section_ of a .wasm.
+
+```bash
+$ /opt/wabt-1.0.31/bin/wasm-objdump -j Import -x <some_example>.wasm
+
+Section Details:
+
+Import[27]:
+ - func[0] sig=2 <pthread_mutex_lock> <- env.pthread_mutex_lock
+ - func[1] sig=2 <pthread_mutex_unlock> <- env.pthread_mutex_unlock
+ - func[2] sig=2 <pthread_cond_signal> <- env.pthread_cond_signal
+ - func[3] sig=3 <host_log> <- env.log
+ ...
+ - func[11] sig=4 <__imported_wasi_snapshot_preview1_sock_bind> <- wasi_snapshot_preview1.sock_bind
+ - func[12] sig=4 <__imported_wasi_snapshot_preview1_sock_connect> <- wasi_snapshot_preview1.sock_connect
+ - func[13] sig=4 <__imported_wasi_snapshot_preview1_sock_listen> <- wasi_snapshot_preview1.sock_listen
+ - func[14] sig=5 <__imported_wasi_snapshot_preview1_sock_open> <- wasi_snapshot_preview1.sock_open
+ - func[15] sig=4 <__imported_wasi_snapshot_preview1_sock_addr_remote> <- wasi_snapshot_preview1.sock_addr_remote
+ - func[16] sig=4 <__imported_wasi_snapshot_preview1_args_get> <- wasi_snapshot_preview1.args_get
+ - func[17] sig=4 <__imported_wasi_snapshot_preview1_args_sizes_get> <- wasi_snapshot_preview1.args_sizes_get
+ ...
+```
+
+Developers should fill in _imports_ with enough host functions and make sure
+there are no linking problems during instantiation.
+
+```bash
+TODO: linking warnings
+```
+
+## A natural way
+
+One natural answer is "to create a list which matches every item in _the import
+section_" of the .wasm. Since developers can see the section details of
+a .wasm by tools like _wasm-objdump_, the answer is doable. Most of the time,
+if they also prepare Wasm modules, developers have full control over import
+requirements, and they only need to take a look at the order of _the import
+section_.
+
+Yes, _the order_. A proper `wasm_extern_vec_t *imports` includes two things:
+
+1. how many `wasm_extern_t`
+2. and order of those
+
+Because there is no "name information" in a `wasm_extern_t`. The only way is let
+`wasm_instance_new()` to tell which item in _the import section_ of a .wasm
+should match any item in `wasm_extern_vec_t *imports` is based on **_index_**.
+
+The algorithm is quite straightforward. The first one of _the import section_ matches
+`wasm_extern_vec_t *imports->data[0] `. The second one matches `wasm_extern_vec_t *imports->data[1]`.
+And so on.
+
+So the order of `wasm_extern_vec_t *imports` becomes quite a burden. It requires
+developers always checking _the import section_ visually.
+
+Until here, the natural way is still workable although involving some handy work.
+Right?
+
+## A blocker
+
+Sorry, the situation changes a lot when driving wasm32-wasi Wasm modules with
+wasm-c-api.
+
+As you know, WASI provides _a set of crossing-platform standard libraries_ for
+Wasm modules, and leaves some _interfaces_ for native platform-dependent supports.
+Those _interfaces_ are those import items with the module name `wasi_snapshot_preview1`
+in a Wasm module.
+
+It seems not economical to let developers provide their version of host
+implementations of the `wasi_snapshot_preview1.XXX` functions. All those support
+should be packed into a common library and shared in different Wasm modules.
+Like a [cargo WASI](https://github.com/bytecodealliance/cargo-wasi).
+
+WAMR chooses to integrate the WASI support library in the runtime to reduce
+developers' compilation work. It brings developers a new thing of a proper
+`wasm_extern_vec_t *imports` that developers should avoid overwriting those items
+of _the import section_ of a Wasm module that will be provided by the runtime. It
+also not economical to code for those functions.
+
+Using module names as a filter seems to be a simple way. But some private
+additional c/c++ libraries are supported in WAMR. Those supporting will bring
+more import items that don't use `wasi_snapshot_preview1` as module names but are still
+covered by the WASM runtime. Like `env.pthread_`. Plus, [the native lib registeration](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md)
+provides another possible way to fill in the requirement of _the import section_.
+
+Let's take summarize. A proper `wasm_extern_vec_t *imports` should include:
+
+1. provides all necessary host implementations for items in _the import section_
+2. should not override runtime provided implementation or covered by native
+ registrations. functinal or econmical.
+3. keep them in a right order
+
+## A recommendation
+
+The recommendation is:
+
+- use `wasm_module_imports()` to build the order
+- use `wasm_importtype_is_linked()` to avoid overwriting
+
+[wasm-c-api-imports](.) is a simple showcase of how to do that.
+
+First, let's take a look at the Wasm module. [send_recv](./wasm/send_recv.c)
+uses both standard WASI and WAMR_BUILD_LIB_PTHREAD supporting. Plus a private
+native function `host_log`.
+
+So, `wasm_extern_vec_t *imports` should only include the host implementation of
+`host_log` and avoid WASI related(`wasm-c-api-imports.XXX`) and pthread related(`env.pthread_XXX`).
+
+[Here is how to do](./host/example1.c):
+
+- get import types with `wasm_module_imports(0)`. it contains name information
+
+```c
+ wasm_importtype_vec_t importtypes = { 0 };
+ wasm_module_imports(module, &importtypes);
+```
+
+- traversal import types. The final `wasm_importvec_t *imports` should have the
+ same order with `wasm_importtype_vec_t`
+
+```c
+ for (unsigned i = 0; i < importtypes.num_elems; i++)
+```
+
+- use `wasm_importtype_is_linked()` to avoid those covered by the runtime and
+ registered natives. A little tip is use "wasm_extern_new_empty()" to create
+ a placeholder.
+
+```c
+ /* use wasm_extern_new_empty() to create a placeholder */
+ if (wasm_importtype_is_linked(importtype)) {
+ externs[i] = wasm_extern_new_empty(
+ store, wasm_externtype_kind(wasm_importtype_type(importtype)));
+ continue;
+ }
+```
+
+- use `wasm_importtype_module()` to get the module name, use `wasm_importtype_name()`
+ to get the field name.
+
+```c
+ const wasm_name_t *module_name =
+ wasm_importtype_module(importtypes.data[i]);
+ const wasm_name_t *field_name =
+ wasm_importtype_name(importtypes.data[i]);
+```
+
+- fill in `wasm_externvec_t *imports` dynamically and programmatically.
+
+```c
+ if (strncmp(module_name->data, "env", strlen("env")) == 0
+ && strncmp(field_name->data, "log", strlen("log")) == 0) {
+ wasm_functype_t *log_type = wasm_functype_new_2_0(
+ wasm_valtype_new_i64(), wasm_valtype_new_i32());
+ wasm_func_t *log_func = wasm_func_new(store, log_type, host_logs);
+ wasm_functype_delete(log_type);
+
+ externs[i] = wasm_func_as_extern(log_func);
+ }
+ }
+```
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/CMakeLists.txt b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/CMakeLists.txt
new file mode 100644
index 000000000..e2636f09e
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required(VERSION 3.14)
+project(host)
+
+set(CMAKE_BUILD_TYPE Debug)
+
+#
+# host
+add_executable(example1 ./example1.c)
+target_link_libraries(example1 vmlib)
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/example1.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/example1.c
new file mode 100644
index 000000000..ccf574d79
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/host/example1.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "wasm_c_api.h"
+#include "wasm_export.h"
+
+static wasm_trap_t *
+host_logs(const wasm_val_vec_t *args, wasm_val_vec_t *results)
+{
+ return NULL;
+}
+
+static bool
+build_imports(wasm_store_t *store, const wasm_module_t *module,
+ wasm_extern_vec_t *out)
+{
+ wasm_importtype_vec_t importtypes = { 0 };
+ wasm_module_imports(module, &importtypes);
+
+ wasm_extern_t *externs[32] = { 0 };
+
+ for (unsigned i = 0; i < importtypes.num_elems; i++) {
+ wasm_importtype_t *importtype = importtypes.data[i];
+
+ /* use wasm_extern_new_empty() to create a placeholder */
+ if (wasm_importtype_is_linked(importtype)) {
+ externs[i] = wasm_extern_new_empty(
+ store, wasm_externtype_kind(wasm_importtype_type(importtype)));
+ continue;
+ }
+
+ const wasm_name_t *module_name =
+ wasm_importtype_module(importtypes.data[i]);
+ const wasm_name_t *field_name =
+ wasm_importtype_name(importtypes.data[i]);
+
+ if (strncmp(module_name->data, "env", strlen("env")) == 0
+ && strncmp(field_name->data, "log", strlen("log")) == 0) {
+ wasm_functype_t *log_type = wasm_functype_new_2_0(
+ wasm_valtype_new_i64(), wasm_valtype_new_i32());
+ wasm_func_t *log_func = wasm_func_new(store, log_type, host_logs);
+ wasm_functype_delete(log_type);
+
+ externs[i] = wasm_func_as_extern(log_func);
+ }
+ }
+
+ wasm_extern_vec_new(out, importtypes.num_elems, externs);
+ wasm_importtype_vec_delete(&importtypes);
+ return true;
+}
+
+int
+main()
+{
+ int main_ret = EXIT_FAILURE;
+
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t *engine = wasm_engine_new();
+ if (!engine)
+ goto quit;
+
+ wasm_store_t *store = wasm_store_new(engine);
+ if (!store)
+ goto delete_engine;
+
+ // Load binary.
+ printf("Loading binary...\n");
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
+ FILE *file = fopen("send_recv.aot", "rb");
+ printf("> Load .aot\n");
+#else
+ FILE *file = fopen("send_recv.wasm", "rb");
+ printf("> Load .wasm\n");
+#endif
+ if (!file) {
+ printf("> Error loading module!\n");
+ goto delete_store;
+ }
+
+ int ret = fseek(file, 0L, SEEK_END);
+ if (ret == -1) {
+ printf("> Error loading module!\n");
+ goto close_file;
+ }
+
+ long file_size = ftell(file);
+ if (file_size == -1) {
+ printf("> Error loading module!\n");
+ goto close_file;
+ }
+
+ ret = fseek(file, 0L, SEEK_SET);
+ if (ret == -1) {
+ printf("> Error loading module!\n");
+ goto close_file;
+ }
+
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ goto delete_binary;
+ }
+
+ // Compile.
+ printf("Compiling module...\n");
+ wasm_module_t *module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ goto delete_binary;
+ }
+
+ // Set Wasi Context
+ const char *addr_pool[1] = { "127.0.0.1" };
+ wasm_runtime_set_wasi_addr_pool(*module, addr_pool, 1);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ wasm_extern_vec_t imports = { 0 };
+ ret = build_imports(store, module, &imports);
+ if (!ret) {
+ printf("> Error building imports!\n");
+ goto delete_module;
+ }
+
+ wasm_instance_t *instance =
+ wasm_instance_new(store, module, &imports, NULL);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ goto delete_imports;
+ }
+
+ // Extract export.
+ printf("Extracting export...\n");
+ wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size == 0) {
+ printf("> Error accessing exports!\n");
+ goto delete_instance;
+ }
+
+ /**
+ * should use information from wasm_module_exports to avoid hard coding "1"
+ */
+ const wasm_func_t *start_func = wasm_extern_as_func(exports.data[1]);
+ if (start_func == NULL) {
+ printf("> Error accessing export!\n");
+ goto delete_exports;
+ }
+
+ // Call. "_start(nil) -> i32"
+ printf("Calling _start ...\n");
+ wasm_val_t rs[1] = { WASM_I32_VAL(0) };
+ wasm_val_vec_t args = WASM_EMPTY_VEC;
+ wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
+ wasm_trap_t *trap = wasm_func_call(start_func, &args, &results);
+ if (trap) {
+ wasm_name_t message = { 0 };
+ wasm_trap_message(trap, &message);
+
+ printf("> Error calling function! %s\n", message.data);
+
+ wasm_name_delete(&message);
+ wasm_trap_delete(trap);
+ goto delete_exports;
+ }
+
+ // Print result.
+ printf("Printing result...\n");
+ printf("> %u\n", rs[0].of.i32);
+
+ // Shut down.
+ printf("Shutting down...\n");
+
+ // All done.
+ printf("Done.\n");
+ main_ret = EXIT_SUCCESS;
+
+delete_exports:
+ wasm_extern_vec_delete(&exports);
+delete_instance:
+ wasm_instance_delete(instance);
+delete_imports:
+ wasm_extern_vec_delete(&imports);
+delete_module:
+ wasm_module_delete(module);
+delete_binary:
+ wasm_byte_vec_delete(&binary);
+close_file:
+ fclose(file);
+delete_store:
+ wasm_store_delete(store);
+delete_engine:
+ wasm_engine_delete(engine);
+quit:
+ return main_ret;
+} \ No newline at end of file
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/CMakeLists.txt b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/CMakeLists.txt
new file mode 100644
index 000000000..6b2743cb5
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required (VERSION 3.14)
+project(wasm_modules)
+
+if(NOT SOCKET_WASI_CMAKE)
+ message(FATAL_ERROR "Require SOCKET_WASI_CMAKE")
+endif()
+
+option(WASM_TO_AOT "transfer wasm to aot" OFF)
+if(WASM_TO_AOT AND NOT WAMRC_PATH)
+ message(FATAL_ERROR "Require WAMRC_PATH when WASM_TO_AOT is ON")
+endif()
+
+#
+# c -> wasm
+include(${SOCKET_WASI_CMAKE})
+add_executable(send_recv ${CMAKE_CURRENT_LIST_DIR}/send_recv.c)
+set_target_properties(send_recv PROPERTIES SUFFIX .wasm)
+target_include_directories(send_recv PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc)
+target_link_libraries(send_recv socket_wasi_ext)
+target_link_options(send_recv PRIVATE
+ LINKER:--export=__heap_base
+ LINKER:--export=__data_end
+ LINKER:--shared-memory,--max-memory=196608
+ LINKER:--no-check-features
+ LINKER:--allow-undefined
+)
+
+if(WASM_TO_AOT)
+ # wasm -> aot
+ add_custom_target(send_recv_aot ALL
+ COMMAND pwd && ${WAMRC_PATH} --enable-multi-thread -o ./send_recv.aot ./send_recv.wasm
+ DEPENDS send_recv
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endif()
+
+#
+# install
+if(WASM_TO_AOT)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/send_recv.aot DESTINATION . )
+else()
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/send_recv.wasm DESTINATION . )
+endif()
+
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/inc/.gitkeep b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/inc/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/inc/.gitkeep
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/send_recv.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/send_recv.c
new file mode 100644
index 000000000..d9f95573a
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/samples/wasm-c-api-imports/wasm/send_recv.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#ifdef __wasi__
+#include <wasi_socket_ext.h>
+#include "pthread.h"
+#else
+#include <pthread.h>
+#endif
+
+static pthread_mutex_t lock = { 0 };
+static pthread_cond_t cond = { 0 };
+static bool server_create_failed = false;
+static bool server_is_ready = false;
+
+#ifdef __wasi__
+__attribute__((import_name("log"))) extern void
+host_log(uint64_t message, uint32_t length);
+#endif
+
+static void
+local_printf(const char *formatter, ...)
+{
+ char buffer[128] = { 0 };
+ va_list args;
+
+ va_start(args, formatter);
+ vsnprintf(buffer, 128, formatter, args);
+ va_end(args);
+
+#ifdef __wasi__
+ host_log((uint64_t)(void *)buffer, strlen(buffer));
+#endif
+ printf("--> %s", buffer);
+}
+
+void *
+run_as_server(void *arg)
+{
+ int sock = -1, on = 1;
+ struct sockaddr_in addr = { 0 };
+ int addrlen = 0;
+ int new_sock = -1;
+ char *buf[] = {
+ "The stars shine down", "It brings us light", "Light comes down",
+ "To make us paths", "It watches us", "And mourns for us",
+ };
+ struct iovec iov[] = {
+ { .iov_base = buf[0], .iov_len = strlen(buf[0]) + 1 },
+ { .iov_base = buf[1], .iov_len = strlen(buf[1]) + 1 },
+ { .iov_base = buf[2], .iov_len = strlen(buf[2]) + 1 },
+ { .iov_base = buf[3], .iov_len = strlen(buf[3]) + 1 },
+ { .iov_base = buf[4], .iov_len = strlen(buf[4]) + 1 },
+ { .iov_base = buf[5], .iov_len = strlen(buf[5]) + 1 },
+ };
+ struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 6 };
+ ssize_t send_len = 0;
+
+ pthread_mutex_lock(&lock);
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ server_create_failed = true;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&lock);
+ perror("Create a socket failed");
+ return NULL;
+ }
+
+#ifndef __wasi__
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) {
+ server_create_failed = true;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&lock);
+ perror("Setsockopt failed");
+ goto fail1;
+ }
+#endif
+
+ /* 0.0.0.0:1234 */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(1234);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ addrlen = sizeof(addr);
+ if (bind(sock, (struct sockaddr *)&addr, addrlen) < 0) {
+ server_create_failed = true;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&lock);
+ perror("Bind failed");
+ goto fail1;
+ }
+
+ if (listen(sock, 0) < 0) {
+ server_create_failed = true;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&lock);
+ perror("Listen failed");
+ goto fail1;
+ }
+
+ server_is_ready = true;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&lock);
+
+ local_printf("Server is online ... \n");
+
+ new_sock = accept(sock, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
+ if (new_sock < 0) {
+ perror("Accept failed");
+ goto fail1;
+ }
+
+ local_printf("Start sending. \n");
+ send_len = sendmsg(new_sock, &msg, 0);
+ if (send_len < 0) {
+ perror("Sendmsg failed");
+ goto fail2;
+ }
+ local_printf("Send %ld bytes successfully!\n", send_len);
+
+fail2:
+ close(new_sock);
+fail1:
+ shutdown(sock, SHUT_RD);
+ close(sock);
+ return NULL;
+}
+
+void *
+run_as_client(void *arg)
+{
+ int sock = -1;
+ struct sockaddr_in addr = { 0 };
+ /* buf of server is 106 bytes */
+ char buf[110] = { 0 };
+ struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
+ struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 };
+ ssize_t recv_len = 0;
+
+ pthread_mutex_lock(&lock);
+ while (!server_create_failed && !server_is_ready) {
+ pthread_cond_wait(&cond, &lock);
+ }
+ pthread_mutex_unlock(&lock);
+
+ if (server_create_failed) {
+ return NULL;
+ }
+
+ local_printf("Client is running...\n");
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("Create a socket failed");
+ return NULL;
+ }
+
+ /* 127.0.0.1:1234 */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(1234);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror("Connect failed");
+ goto fail;
+ }
+
+ local_printf("Start receiving. \n");
+ recv_len = recvmsg(sock, &msg, 0);
+ if (recv_len < 0) {
+ perror("Recvmsg failed");
+ goto fail;
+ }
+
+ local_printf("Receive %ld bytes successlly!\n", recv_len);
+ assert(recv_len == 106);
+
+ local_printf("Data:\n");
+ char *s = msg.msg_iov->iov_base;
+ while (strlen(s) > 0) {
+ local_printf(" %s\n", s);
+ s += strlen(s) + 1;
+ }
+
+fail:
+ shutdown(sock, SHUT_RD);
+ close(sock);
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t cs[2] = { 0 };
+ uint8_t i = 0;
+ int ret = EXIT_SUCCESS;
+
+ if (pthread_mutex_init(&lock, NULL)) {
+ perror("Initialize mutex failed");
+ ret = EXIT_FAILURE;
+ goto RETURN;
+ }
+
+ if (pthread_cond_init(&cond, NULL)) {
+ perror("Initialize condition failed");
+ ret = EXIT_FAILURE;
+ goto DESTROY_MUTEX;
+ }
+
+ if (pthread_create(&cs[0], NULL, run_as_server, NULL)) {
+ perror("Create a server thread failed");
+ ret = EXIT_FAILURE;
+ goto DESTROY_COND;
+ }
+
+ if (pthread_create(&cs[1], NULL, run_as_client, NULL)) {
+ perror("Create a client thread failed");
+ ret = EXIT_FAILURE;
+ goto DESTROY_COND;
+ }
+
+ for (i = 0; i < 2; i++) {
+ pthread_join(cs[i], NULL);
+ }
+
+DESTROY_COND:
+ pthread_cond_destroy(&cond);
+DESTROY_MUTEX:
+ pthread_mutex_destroy(&lock);
+RETURN:
+ return ret;
+}