Merge pull request #1032 from bytecodealliance/main

Merge main into dev/fast_jit
This commit is contained in:
Wenyong Huang 2022-03-09 09:40:26 +08:00 committed by GitHub
commit 3c39054317
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 314 additions and 56 deletions

View File

@ -11,6 +11,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_android_ubuntu_macos.yml"
# will be triggered on push events
push:
paths-ignore:
@ -18,6 +19,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_android_ubuntu_macos.yml"
# allow to be triggered manually
workflow_dispatch:

View File

@ -11,6 +11,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_sgx.yml"
# will be triggered on push events
push:
paths-ignore:
@ -18,6 +19,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_sgx.yml"
# allow to be triggered manually
workflow_dispatch:

View File

@ -11,6 +11,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_windows.yml"
# will be triggered on push events
push:
paths-ignore:
@ -18,6 +19,7 @@ on:
- "ci/**"
- "doc/**"
- "test-tools/**"
- ".github/workflows/compilation_on_windows.yml"
# allow to be triggered manually
workflow_dispatch:

View File

@ -13,6 +13,7 @@ on:
- "product-mini/**"
- "tests/wamr-test-suites/spec-test-script/**"
- "tests/wamr-test-suites/test_wamr.sh"
- ".github/workflows/spec_test.yml"
# will be triggered on push events
push:
paths:
@ -23,6 +24,7 @@ on:
- "product-mini/**"
- "tests/wamr-test-suites/spec-test-script/**"
- "tests/wamr-test-suites/test_wamr.sh"
- ".github/workflows/spec_test.yml"
# allow to be triggered manually
workflow_dispatch:
@ -140,7 +142,13 @@ jobs:
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
- name: install Ninja and x32 support libraries
run: sudo apt install -y g++-multilib libgcc-9-dev lib32gcc-9-dev ninja-build
run:
# Add another apt repository as some packages cannot
# be downloaded with the github default repository
sudo curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc &&
sudo apt-add-repository https://packages.microsoft.com/ubuntu/20.04/prod &&
sudo apt-get update &&
sudo apt install -y g++-multilib lib32gcc-9-dev ninja-build
- name: run spec tests
run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }}

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
.cache
.vs
.vscode
/.idea

View File

@ -113,6 +113,7 @@ typedef struct {
REG_SYM(aot_call_indirect), \
REG_SYM(aot_enlarge_memory), \
REG_SYM(aot_set_exception), \
REG_SYM(aot_check_app_addr_and_convert),\
{ "memset", (void*)aot_memset }, \
{ "memmove", (void*)aot_memmove }, \
{ "memcpy", (void*)aot_memmove }, \

View File

@ -2431,6 +2431,56 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
}
}
/**
* Check whether the app address and the buf is inside the linear memory,
* and convert the app address into native address
*/
bool
aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
uint32 app_buf_addr, uint32 app_buf_size,
void **p_native_addr)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
uint8 *native_addr;
if (!memory_inst) {
goto fail;
}
native_addr = (uint8 *)memory_inst->memory_data.ptr + app_buf_addr;
/* No need to check the app_offset and buf_size if memory access
boundary check with hardware trap is enabled */
#ifndef OS_ENABLE_HW_BOUND_CHECK
if (app_buf_addr >= memory_inst->memory_data_size) {
goto fail;
}
if (!is_str) {
if (app_buf_size > memory_inst->memory_data_size - app_buf_addr) {
goto fail;
}
}
else {
const char *str, *str_end;
/* The whole string must be in the linear memory */
str = (const char *)native_addr;
str_end = (const char *)memory_inst->memory_data_end.ptr;
while (str < str_end && *str != '\0')
str++;
if (str == str_end)
goto fail;
}
#endif
*p_native_addr = (void *)native_addr;
return true;
fail:
aot_set_exception(module_inst, "out of bounds memory access");
return false;
}
void *
aot_memmove(void *dest, const void *src, size_t n)
{

View File

@ -647,6 +647,11 @@ bool
aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
uint32 argc, uint32 *argv);
bool
aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
uint32 app_buf_addr, uint32 app_buf_size,
void **p_native_addr);
uint32
aot_get_plt_table_size();

View File

@ -1947,6 +1947,10 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
for (i = 0; i != import_count; ++i) {
char *module_name_rt = NULL, *field_name_rt = NULL;
memset(&module_name, 0, sizeof(wasm_val_vec_t));
memset(&name, 0, sizeof(wasm_val_vec_t));
extern_type = NULL;
if (i < import_func_count) {
wasm_functype_t *type = NULL;
WASMType *type_rt = NULL;
@ -1974,16 +1978,6 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
continue;
}
wasm_name_new_from_string(&module_name, module_name_rt);
if (strlen(module_name_rt) && !module_name.data) {
goto failed;
}
wasm_name_new_from_string(&name, field_name_rt);
if (strlen(field_name_rt) && !name.data) {
goto failed;
}
if (!(type = wasm_functype_new_internal(type_rt))) {
goto failed;
}
@ -2061,16 +2055,6 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
continue;
}
wasm_name_new_from_string(&module_name, module_name_rt);
if (strlen(module_name_rt) && !module_name.data) {
goto failed;
}
wasm_name_new_from_string(&name, field_name_rt);
if (strlen(field_name_rt) && !name.data) {
goto failed;
}
if (!(type = wasm_memorytype_new_internal(min_page, max_page))) {
goto failed;
}
@ -2122,8 +2106,16 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
extern_type = wasm_tabletype_as_externtype(type);
}
if (!extern_type) {
continue;
bh_assert(extern_type);
wasm_name_new_from_string(&module_name, module_name_rt);
if (strlen(module_name_rt) && !module_name.data) {
goto failed;
}
wasm_name_new_from_string(&name, field_name_rt);
if (strlen(field_name_rt) && !name.data) {
goto failed;
}
if (!(import_type =
@ -2134,9 +2126,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
if (!bh_vector_append((Vector *)out, &import_type)) {
goto failed_importtype_new;
}
}
return;
continue;
failed:
wasm_byte_vec_delete(&module_name);
@ -2144,7 +2135,7 @@ failed:
wasm_externtype_delete(extern_type);
failed_importtype_new:
wasm_importtype_delete(import_type);
wasm_importtype_vec_delete(out);
}
}
void

View File

@ -518,6 +518,111 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return true;
}
/**
* Check whether the app address and its buffer are inside the linear memory,
* if no, throw exception
*/
static bool
check_app_addr_and_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool is_str_arg, LLVMValueRef app_addr,
LLVMValueRef buf_size,
LLVMValueRef *p_native_addr_converted)
{
LLVMTypeRef func_type, func_ptr_type, func_param_types[5];
LLVMValueRef func, func_param_values[5], res, native_addr_ptr;
char *func_name = "aot_check_app_addr_and_convert";
/* prepare function type of aot_check_app_addr_and_convert */
func_param_types[0] = comp_ctx->aot_inst_type; /* module_inst */
func_param_types[1] = INT8_TYPE; /* is_str_arg */
func_param_types[2] = I32_TYPE; /* app_offset */
func_param_types[3] = I32_TYPE; /* buf_size */
func_param_types[4] =
comp_ctx->basic_types.int8_pptr_type; /* p_native_addr */
if (!(func_type =
LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
aot_set_last_error("llvm add function type failed.");
return false;
}
/* prepare function pointer */
if (comp_ctx->is_jit_mode) {
if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
aot_set_last_error("create LLVM function type failed.");
return false;
}
/* JIT mode, call the function directly */
if (!(func =
I64_CONST((uint64)(uintptr_t)aot_check_app_addr_and_convert))
|| !(func = LLVMConstIntToPtr(func, func_ptr_type))) {
aot_set_last_error("create LLVM value failed.");
return false;
}
}
else if (comp_ctx->is_indirect_mode) {
int32 func_index;
if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
aot_set_last_error("create LLVM function type failed.");
return false;
}
func_index = aot_get_native_symbol_index(comp_ctx, func_name);
if (func_index < 0) {
return false;
}
if (!(func = aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
func_ptr_type, func_index))) {
return false;
}
}
else {
if (!(func = LLVMGetNamedFunction(func_ctx->module, func_name))
&& !(func =
LLVMAddFunction(func_ctx->module, func_name, func_type))) {
aot_set_last_error("add LLVM function failed.");
return false;
}
}
if (!(native_addr_ptr = LLVMBuildBitCast(
comp_ctx->builder, func_ctx->argv_buf,
comp_ctx->basic_types.int8_pptr_type, "p_native_addr"))) {
aot_set_last_error("llvm build bit cast failed.");
return false;
}
func_param_values[0] = func_ctx->aot_inst;
func_param_values[1] = I8_CONST(is_str_arg);
func_param_values[2] = app_addr;
func_param_values[3] = buf_size;
func_param_values[4] = native_addr_ptr;
if (!func_param_values[1]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_check_app_addr_and_convert() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 5,
"res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
/* Check whether exception was thrown when executing the function */
if (!check_call_return(comp_ctx, func_ctx, res)) {
return false;
}
if (!(*p_native_addr_converted = LLVMBuildLoad(
comp_ctx->builder, native_addr_ptr, "native_addr"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
return true;
}
bool
aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 func_idx, bool tail_call)
@ -539,6 +644,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 callee_cell_num;
uint8 wasm_ret_type;
uint8 *ext_ret_types = NULL;
const char *signature = NULL;
bool ret = false;
char buf[32];
@ -557,11 +663,14 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
/* Get function type */
if (func_idx < import_func_count)
if (func_idx < import_func_count) {
func_type = import_funcs[func_idx].func_type;
else
signature = import_funcs[func_idx].signature;
}
else {
func_type =
func_ctxes[func_idx - import_func_count]->aot_func->func_type;
}
/* Get param cell number */
param_cell_num = func_type->param_cell_num;
@ -659,8 +768,41 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
j = 0;
param_types[j++] = comp_ctx->exec_env_type;
for (i = 0; i < param_count; i++)
param_types[j++] = TO_LLVM_TYPE(func_type->types[i]);
for (i = 0; i < param_count; i++, j++) {
param_types[j] = TO_LLVM_TYPE(func_type->types[i]);
/* If the signature can be gotten, e.g. the signature of the builtin
native libraries, just check the app offset and buf size, and
then convert app offset to native addr and call the native func
directly, no need to call aot_invoke_native to call it */
if (signature) {
LLVMValueRef native_addr, native_addr_size;
if (signature[i + 1] == '*' || signature[i + 1] == '$') {
param_types[j] = INT8_PTR_TYPE;
}
if (signature[i + 1] == '*') {
if (signature[i + 2] == '~')
native_addr_size = param_values[i + 2];
else
native_addr_size = I32_ONE;
if (!check_app_addr_and_convert(
comp_ctx, func_ctx, false, param_values[j],
native_addr_size, &native_addr)) {
goto fail;
}
param_values[j] = native_addr;
}
else if (signature[i + 1] == '$') {
native_addr_size = I32_ZERO;
if (!check_app_addr_and_convert(
comp_ctx, func_ctx, true, param_values[j],
native_addr_size, &native_addr)) {
goto fail;
}
param_values[j] = native_addr;
}
}
}
if (func_type->result_count) {
wasm_ret_type = func_type->types[func_type->param_count];
@ -671,18 +813,69 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ret_type = VOID_TYPE;
}
if (!signature) {
/* call aot_invoke_native() */
if (!call_aot_invoke_native_func(
comp_ctx, func_ctx, import_func_idx, func_type, param_types + 1,
param_values + 1, param_count, param_cell_num, ret_type,
wasm_ret_type, &value_ret, &res))
comp_ctx, func_ctx, import_func_idx, func_type,
param_types + 1, param_values + 1, param_count,
param_cell_num, ret_type, wasm_ret_type, &value_ret, &res))
goto fail;
/* Check whether there was exception thrown when executing
the function */
if (!check_call_return(comp_ctx, func_ctx, res))
goto fail;
}
else { /* call native func directly */
LLVMTypeRef native_func_type, func_ptr_type;
LLVMValueRef func_ptr;
if (!(native_func_type = LLVMFunctionType(
ret_type, param_types, param_count + 1, false))) {
aot_set_last_error("llvm add function type failed.");
goto fail;
}
if (!(func_ptr_type = LLVMPointerType(native_func_type, 0))) {
aot_set_last_error("create LLVM function type failed.");
goto fail;
}
/* Load function pointer */
if (!(func_ptr = LLVMBuildInBoundsGEP(
comp_ctx->builder, func_ctx->func_ptrs, &import_func_idx,
1, "native_func_ptr_tmp"))) {
aot_set_last_error("llvm build inbounds gep failed.");
goto fail;
}
if (!(func_ptr = LLVMBuildLoad(comp_ctx->builder, func_ptr,
"native_func_ptr"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
if (!(func = LLVMBuildBitCast(comp_ctx->builder, func_ptr,
func_ptr_type, "native_func"))) {
aot_set_last_error("llvm bit cast failed.");
goto fail;
}
/* Call the function */
if (!(value_ret = LLVMBuildCall(
comp_ctx->builder, func, param_values,
(uint32)param_count + 1 + ext_ret_count,
(func_type->result_count > 0 ? "call" : "")))) {
aot_set_last_error("LLVM build call failed.");
goto fail;
}
/* Check whether there was exception thrown when executing
the function */
if (!check_exception_thrown(comp_ctx, func_ctx)) {
goto fail;
}
}
}
else {
bool recursive_call =
(func_ctx == func_ctxes[func_idx - import_func_count]) ? true

View File

@ -74,12 +74,12 @@ else ifeq (${WAMR_BUILD_TARGET}, XTENSA)
AOT_RELOC := aot_reloc_xtensa.c
else ifeq (${WAMR_BUILD_TARGET}, RISCV64)
ifeq (${CONFIG_ARCH_FPU},y)
$(error riscv64 lp64f is unsupported)
else ifeq (${CONFIG_ARCH_DPFPU}, y)
ifeq (${CONFIG_ARCH_DPFPU},y)
CFLAGS += -DBUILD_TARGET_RISCV64_LP64D
else
else ifneq (${CONFIG_ARCH_FPU},y)
CFLAGS += -DBUILD_TARGET_RISCV64_LP64
else
$(error riscv64 lp64f is unsupported)
endif
INVOKE_NATIVE += invokeNative_riscv.S
@ -87,12 +87,12 @@ endif
else ifeq (${WAMR_BUILD_TARGET}, RISCV32)
ifeq (${CONFIG_ARCH_FPU}, y)
$(error riscv32 ilp32f is unsupported)
else ifeq (${CONFIG_ARCH_DPFPU}, y)
ifeq (${CONFIG_ARCH_DPFPU},y)
CFLAGS += -DBUILD_TARGET_RISCV32_ILP32D
else
else ifneq (${CONFIG_ARCH_FPU},y)
CFLAGS += -DBUILD_TARGET_RISCV32_ILP32
else
$(error riscv32 ilp32f is unsupported)
endif
INVOKE_NATIVE += invokeNative_riscv.S

View File

@ -181,6 +181,8 @@ include (${SHARED_DIR}/utils/shared_utils.cmake)
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
include (${IWASM_DIR}/libraries/thread-mgr/thread_mgr.cmake)
include (${IWASM_DIR}/libraries/libc-builtin/libc_builtin.cmake)
include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake)
include (${IWASM_DIR}/libraries/lib-pthread/lib_pthread.cmake)
include (${IWASM_DIR}/common/iwasm_common.cmake)
include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)
include (${IWASM_DIR}/aot/iwasm_aot.cmake)
@ -239,6 +241,8 @@ add_library (vmlib
${UNCOMMON_SHARED_SOURCE}
${THREAD_MGR_SOURCE}
${LIBC_BUILTIN_SOURCE}
${LIBC_WASI_SOURCE}
${LIB_PTHREAD_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE})