Implement multi-module feature and bulk-memory feature (#271)
Refine wasm loader and aot loader Fix potential issue of os_mmap/os_munmap Update document
This commit is contained in:
51
samples/multi-module/CMakeLists.txt
Normal file
51
samples/multi-module/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(multi_module)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
################ runtime settings ################
|
||||
set(WAMR_BUILD_PLATFORM "linux")
|
||||
|
||||
# Resetdefault 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(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_AOT 0)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
set(WAMR_BUILD_FAST_INTERP 0)
|
||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||
|
||||
# compiling and linking 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 -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 STATIC ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
################################################
|
||||
|
||||
################ application related ################
|
||||
|
||||
################ WASM MODULES
|
||||
# .c -> .wasm
|
||||
add_subdirectory(wasm-apps)
|
||||
|
||||
################ NATIVE
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
add_executable(multi_module src/main.c ${UNCOMMON_SHARED_SOURCE})
|
||||
|
||||
add_dependencies(multi_module vmlib wasm-modules)
|
||||
|
||||
# libraries
|
||||
target_link_libraries(multi_module PRIVATE vmlib -lpthread -lm)
|
||||
144
samples/multi-module/src/main.c
Normal file
144
samples/multi-module/src/main.c
Normal file
@ -0,0 +1,144 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "platform_common.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
static char *
|
||||
build_module_path(const char *module_name)
|
||||
{
|
||||
const char *module_search_path = "./wasm-apps";
|
||||
const char *format = "%s/%s.wasm";
|
||||
int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
|
||||
+ strlen(".wasm") + 1;
|
||||
char *wasm_file_name = BH_MALLOC(sz);
|
||||
if (!wasm_file_name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(wasm_file_name, sz, format, module_search_path, module_name);
|
||||
return wasm_file_name;
|
||||
}
|
||||
|
||||
static bool
|
||||
module_reader_cb(const char *module_name, uint8 **p_buffer, uint32 *p_size)
|
||||
{
|
||||
char *wasm_file_path = build_module_path(module_name);
|
||||
if (!wasm_file_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("- bh_read_file_to_buffer %s\n", wasm_file_path);
|
||||
*p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_path, p_size);
|
||||
BH_FREE(wasm_file_path);
|
||||
return *p_buffer != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
module_destroyer_cb(uint8 *buffer, uint32 size)
|
||||
{
|
||||
printf("- release the read file buffer\n");
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
BH_FREE(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
/* 10M */
|
||||
static char sandbox_memory_space[10 * 1024 * 1024] = { 0 };
|
||||
int
|
||||
main()
|
||||
{
|
||||
bool ret = false;
|
||||
/* 16K */
|
||||
const uint32 stack_size = 16 * 1024;
|
||||
const uint32 heap_size = 16 * 1024;
|
||||
|
||||
RuntimeInitArgs init_args = { 0 };
|
||||
char error_buf[128] = { 0 };
|
||||
/* parameters and return values */
|
||||
char* args[1] = { 0 };
|
||||
|
||||
uint8 *file_buf = NULL;
|
||||
uint32 file_buf_size = 0;
|
||||
wasm_module_t module = NULL;
|
||||
wasm_module_inst_t module_inst = NULL;
|
||||
|
||||
/* all malloc() only from the given buffer */
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = sandbox_memory_space;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(sandbox_memory_space);
|
||||
|
||||
printf("- wasm_runtime_full_init\n");
|
||||
/* initialize runtime environment */
|
||||
if (!wasm_runtime_full_init(&init_args)) {
|
||||
printf("Init runtime environment failed.\n");
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
printf("- wasm_runtime_set_module_reader\n");
|
||||
/* set module reader and destroyer */
|
||||
wasm_runtime_set_module_reader(module_reader_cb, module_destroyer_cb);
|
||||
#endif
|
||||
|
||||
/* load WASM byte buffer from WASM bin file */
|
||||
if (!module_reader_cb("mC", &file_buf, &file_buf_size)) {
|
||||
goto RELEASE_RUNTIME;
|
||||
}
|
||||
|
||||
/* load mC and let WAMR load mA and mB */
|
||||
printf("- wasm_runtime_load\n");
|
||||
if (!(module = wasm_runtime_load(file_buf, file_buf_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto RELEASE_BINARY;
|
||||
}
|
||||
|
||||
/* instantiate the module */
|
||||
printf("- wasm_runtime_instantiate\n");
|
||||
if (!(module_inst =
|
||||
wasm_runtime_instantiate(module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto UNLOAD_MODULE;
|
||||
}
|
||||
|
||||
/* call some functions of mC */
|
||||
printf("\n----------------------------------------\n");
|
||||
printf("call \"C\", it will return 0xc:i32, ===> ");
|
||||
wasm_application_execute_func(module_inst, "C", 0, &args[0]);
|
||||
printf("call \"call_B\", it will return 0xb:i32, ===> ");
|
||||
wasm_application_execute_func(module_inst, "call_B", 0, &args[0]);
|
||||
printf("call \"call_A\", it will return 0xa:i32, ===>");
|
||||
wasm_application_execute_func(module_inst, "call_A", 0, &args[0]);
|
||||
|
||||
/* call some functions of mB */
|
||||
printf("call \"mB.B\", it will return 0xb:i32, ===>");
|
||||
wasm_application_execute_func(module_inst, "$mB$B", 0, &args[0]);
|
||||
printf("call \"mB.call_A\", it will return 0xa:i32, ===>");
|
||||
wasm_application_execute_func(module_inst, "$mB$call_A", 0, &args[0]);
|
||||
|
||||
/* call some functions of mA */
|
||||
printf("call \"mA.A\", it will return 0xa:i32, ===>");
|
||||
wasm_application_execute_func(module_inst, "$mA$A", 0, &args[0]);
|
||||
printf("----------------------------------------\n\n");
|
||||
ret = true;
|
||||
|
||||
printf("- wasm_runtime_deinstantiate\n");
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
UNLOAD_MODULE:
|
||||
printf("- wasm_runtime_unload\n");
|
||||
wasm_runtime_unload(module);
|
||||
RELEASE_BINARY:
|
||||
module_destroyer_cb(file_buf, file_buf_size);
|
||||
RELEASE_RUNTIME:
|
||||
printf("- wasm_runtime_destroy\n");
|
||||
wasm_runtime_destroy();
|
||||
EXIT:
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
41
samples/multi-module/wasm-apps/CMakeLists.txt
Normal file
41
samples/multi-module/wasm-apps/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(wasm-apps)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
||||
set(CLANG_COMMAND "/opt/wasi-sdk/bin/clang")
|
||||
|
||||
set(CLANG_FLAGS --target=wasm32 -nostdlib)
|
||||
set(CLANG_FLAGS ${CLANG_FLAGS} -Wl,--no-entry,--allow-undefined,--export-all)
|
||||
|
||||
set(SOURCE_A ${CMAKE_CURRENT_SOURCE_DIR}/mA.c)
|
||||
add_custom_command(
|
||||
OUTPUT mA.wasm
|
||||
COMMENT "Transform mA.C to mA.WASM"
|
||||
COMMAND ${CLANG_COMMAND} ${CLANG_FLAGS} -o mA.wasm ${SOURCE_A}
|
||||
DEPENDS ${SOURCE_A}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(SOURCE_B ${CMAKE_CURRENT_SOURCE_DIR}/mB.c)
|
||||
add_custom_command(
|
||||
OUTPUT mB.wasm
|
||||
COMMENT "Transform mB.C to mB.WASM"
|
||||
COMMAND ${CLANG_COMMAND} ${CLANG_FLAGS} -o mB.wasm ${SOURCE_B}
|
||||
DEPENDS ${SOURCE_B}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(SOURCE_C ${CMAKE_CURRENT_SOURCE_DIR}/mC.c)
|
||||
add_custom_command(
|
||||
OUTPUT mC.wasm
|
||||
COMMENT "Transform mC.C to mC.WASM"
|
||||
COMMAND ${CLANG_COMMAND} ${CLANG_FLAGS} -o mC.wasm ${SOURCE_C}
|
||||
DEPENDS ${SOURCE_C}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(wasm-modules ALL
|
||||
DEPENDS mA.wasm mB.wasm mC.wasm
|
||||
)
|
||||
5
samples/multi-module/wasm-apps/mA.c
Normal file
5
samples/multi-module/wasm-apps/mA.c
Normal file
@ -0,0 +1,5 @@
|
||||
int
|
||||
A()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
16
samples/multi-module/wasm-apps/mB.c
Normal file
16
samples/multi-module/wasm-apps/mB.c
Normal file
@ -0,0 +1,16 @@
|
||||
__attribute__((import_module("mA")))
|
||||
__attribute__((import_name("A"))) extern int
|
||||
A();
|
||||
|
||||
int
|
||||
B()
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
|
||||
int
|
||||
call_A()
|
||||
{
|
||||
return A();
|
||||
}
|
||||
|
||||
25
samples/multi-module/wasm-apps/mC.c
Normal file
25
samples/multi-module/wasm-apps/mC.c
Normal file
@ -0,0 +1,25 @@
|
||||
__attribute__((import_module("mA")))
|
||||
__attribute__((import_name("A"))) extern int
|
||||
A();
|
||||
|
||||
__attribute__((import_module("mB")))
|
||||
__attribute__((import_name("B"))) extern int
|
||||
B();
|
||||
|
||||
int
|
||||
C()
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
int
|
||||
call_A()
|
||||
{
|
||||
return A();
|
||||
}
|
||||
|
||||
int
|
||||
call_B()
|
||||
{
|
||||
return B();
|
||||
}
|
||||
Reference in New Issue
Block a user