Import reference-types feature (#612)

Implement spec reference-types proposal for interpreter, AOT and JIT, update documents and add sample. And upgrade AOT_CURRENT_VERSION to 3 as AOT file format and AOT module instance layout are changed.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang
2021-04-15 11:29:20 +08:00
committed by GitHub
parent 7706e4b151
commit 03d45f1d62
48 changed files with 5557 additions and 856 deletions

View File

@ -0,0 +1,108 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required (VERSION 2.8)
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project(ref-types)
else()
project (ref-types C ASM)
enable_language (ASM_MASM)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
################ 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 "X86_64")
if(NOT DEFINED WAMR_BUILD_INTERP)
set(WAMR_BUILD_INTERP 1)
endif()
if(NOT DEFINED WAMR_BUILD_AOT)
set(WAMR_BUILD_AOT 0)
endif()
if(NOT DEFINED WAMR_BUILD_JOT)
set(WAMR_BUILD_JIT 0)
endif()
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
set(WAMR_BUILD_FAST_INTERP 1)
endif()
if(NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
set(WAMR_BUILD_LIBC_BUILTIN 1)
endif()
# Enable reference-types feature
set(WAMR_BUILD_REF_TYPES 1)
if (NOT MSVC)
# compiling and linking flags
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE")
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")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
endif ()
endif()
# build out vmlib
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
set(WAMRC ${WAMR_ROOT_DIR}/wamr-compiler/build/wamrc)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE})
if (MSVC)
target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=)
endif()
################ application related ################
## locate wat2wasm
find_program(WAT2WASM
wat2wasm
PATHS /opt/wabt/bin
REQUIRED
)
if(NOT WAT2WASM)
message(SEND_ERROR "can not find wat2wasm")
endif()
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
add_executable(hello src/hello.c ${UNCOMMON_SHARED_SOURCE})
target_include_directories(hello PRIVATE ${UNCOMMON_SHARED_DIR})
target_link_libraries(hello vmlib -lpthread -lm)
if (MSVC)
target_compile_definitions(hello PRIVATE WASM_API_EXTERN=)
endif()
# wat to wasm
file(GLOB WAT_FILE src/hello.wat)
add_custom_target(hello_wasm ALL
COMMAND ${WAT2WASM} ${WAT_FILE} -o ${PROJECT_BINARY_DIR}/hello.wasm
DEPENDS ${WAT_FILE}
BYPRODUCTS ${PROJECT_BINARY_DIR}/hello.wasm
VERBATIM
SOURCES ${WAT_FILE}
)

View File

@ -0,0 +1,165 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_read_file.h"
#include "wasm_export.h"
#define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
static int
test_write_wrapper(wasm_exec_env_t exec_env,
uint32 externref_idx_of_file,
const char *str, int len)
{
FILE *file;
char buf[16];
printf("## retrieve file handle from externref index\n");
if (!wasm_externref_ref2obj(externref_idx_of_file, (void **)&file)) {
printf("failed to get host object from externref index!\n");
return -1;
}
snprintf(buf, sizeof(buf), "%%%ds", len);
printf("## write string to file: ");
printf(buf, str);
return fprintf(file, buf, str);
}
static NativeSymbol native_symbols[] = {
{ "test_write", test_write_wrapper, "(i*~)i", NULL }
};
int
main(int argc, char *argv[])
{
char *wasm_file = "hello.wasm";
uint8 *wasm_file_buf = NULL;
uint32 wasm_file_size, externref_idx;
uint32 stack_size = 16 * 1024, heap_size = 16 * 1024;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
wasm_function_inst_t func_inst = NULL;
wasm_exec_env_t exec_env = NULL;
RuntimeInitArgs init_args;
char error_buf[128] = { 0 };
const char *exce;
unsigned argv1[8];
#if WASM_ENABLE_LOG != 0
int log_verbose_level = 2;
#endif
FILE *file;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
#if USE_GLOBAL_HEAP_BUF != 0
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);
#else
init_args.mem_alloc_type = Alloc_With_Allocator;
init_args.mem_alloc_option.allocator.malloc_func = malloc;
init_args.mem_alloc_option.allocator.realloc_func = realloc;
init_args.mem_alloc_option.allocator.free_func = free;
#endif
init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
init_args.native_module_name = "env";
init_args.native_symbols = native_symbols;
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime environment failed.\n");
return -1;
}
#if WASM_ENABLE_LOG != 0
bh_log_set_verbose_level(log_verbose_level);
#endif
/* load WASM byte buffer from WASM bin file */
if (!(wasm_file_buf =
(uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size)))
goto fail1;
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail2;
}
/* instantiate the module */
if (!(wasm_module_inst =
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail3;
}
/* lookup function instance */
if (!(func_inst = wasm_runtime_lookup_function(wasm_module_inst,
"test", NULL))) {
printf("%s\n", "lookup function test failed");
goto fail4;
}
if (!(exec_env =
wasm_runtime_create_exec_env(wasm_module_inst, stack_size))) {
printf("%s\n", "create exec env failed");
goto fail4;
}
printf("## open file test.txt\n");
if (!(file = fopen("test.txt", "wb+"))) {
printf("%s\n", "open file text.txt failed");
goto fail5;
}
printf("## map file handle to externref index\n");
if (!wasm_externref_obj2ref(wasm_module_inst, file, &externref_idx)) {
printf("%s\n", "map host object to externref index failed");
goto fail6;
}
printf("## call wasm function with externref index\n");
argv1[0] = externref_idx;
wasm_runtime_call_wasm(exec_env, func_inst, 1, argv1);
if ((exce = wasm_runtime_get_exception(wasm_module_inst))) {
printf("Exception: %s\n", exce);
}
fail6:
fclose(file);
fail5:
/* destroy exec env */
wasm_runtime_destroy_exec_env(exec_env);
fail4:
/* destroy the module instance */
wasm_runtime_deinstantiate(wasm_module_inst);
fail3:
/* unload the module */
wasm_runtime_unload(wasm_module);
fail2:
/* free the file buffer */
wasm_runtime_free(wasm_file_buf);
fail1:
/* destroy runtime environment */
wasm_runtime_destroy();
return 0;
}

View File

@ -0,0 +1,22 @@
;; Copyright (C) 2019 Intel Corporation. All rights reserved.
;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
(module
;; import test_write function which is implemented by host
(import "env" "test_write"
(func $test_write (param externref i32 i32) (result i32)))
;; memory with one page (64KiB).
(memory (export "memory") 1)
(data (i32.const 0x8) "Hello, world!\n")
;; function that writes string to a given open file handle
(func (export "test") (param externref)
(local.get 0)
(i32.const 0x8)
(i32.const 14)
(call $test_write)
drop
)
)