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:
wenyongh
2020-06-02 14:53:06 +08:00
committed by GitHub
parent e81f72d41f
commit 752826a667
57 changed files with 4902 additions and 818 deletions

View 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)

View 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;
}

View 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
)

View File

@ -0,0 +1,5 @@
int
A()
{
return 10;
}

View 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();
}

View 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();
}