mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-11 20:21:11 +00:00
Compare commits
9 Commits
0d06e428a0
...
f802f6bd90
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f802f6bd90 | ||
![]() |
d053f5534a | ||
![]() |
4735956eeb | ||
![]() |
5910e5cd21 | ||
![]() |
5bdbba0dbe | ||
![]() |
382aa9e6c3 | ||
![]() |
3232bdf2f7 | ||
![]() |
d9325b2549 | ||
![]() |
e3dcf4f8ac |
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3.28.15
|
uses: github/codeql-action/init@v3.28.17
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ jobs:
|
||||||
- run: |
|
- run: |
|
||||||
./.github/scripts/codeql_buildscript.sh
|
./.github/scripts/codeql_buildscript.sh
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3.28.15
|
uses: github/codeql-action/analyze@v3.28.17
|
||||||
with:
|
with:
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
upload: false
|
upload: false
|
||||||
|
@ -99,7 +99,7 @@ jobs:
|
||||||
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
||||||
|
|
||||||
- name: Upload CodeQL results to code scanning
|
- name: Upload CodeQL results to code scanning
|
||||||
uses: github/codeql-action/upload-sarif@v3.28.15
|
uses: github/codeql-action/upload-sarif@v3.28.17
|
||||||
with:
|
with:
|
||||||
sarif_file: ${{ steps.step1.outputs.sarif-output }}
|
sarif_file: ${{ steps.step1.outputs.sarif-output }}
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
|
|
2
.github/workflows/supply_chain.yml
vendored
2
.github/workflows/supply_chain.yml
vendored
|
@ -60,6 +60,6 @@ jobs:
|
||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@4c3e5362829f0b0bb62ff5f6c938d7f95574c306
|
uses: github/codeql-action/upload-sarif@5eb3ed6614230b1931d5c08df9e096e4ba524f21
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|
|
@ -98,9 +98,19 @@ def run_clang_format_diff(root: Path, commits: str) -> bool:
|
||||||
code before committing the PR, or it might fail to pass the CI check:
|
code before committing the PR, or it might fail to pass the CI check:
|
||||||
|
|
||||||
1. Install clang-format-14.0.0
|
1. Install clang-format-14.0.0
|
||||||
Normally we can install it by `sudo apt-get install clang-format-14`,
|
|
||||||
or download the package from https://github.com/llvm/llvm-project/releases
|
You can download the package from
|
||||||
and install it
|
https://github.com/llvm/llvm-project/releases
|
||||||
|
and install it.
|
||||||
|
|
||||||
|
For Debian/Ubuntu, we can probably use
|
||||||
|
`sudo apt-get install clang-format-14`.
|
||||||
|
|
||||||
|
Homebrew has it as a part of llvm@14.
|
||||||
|
```shell
|
||||||
|
brew install llvm@14
|
||||||
|
/usr/local/opt/llvm@14/bin/clang-format
|
||||||
|
```
|
||||||
|
|
||||||
2. Format the C/C++ source file
|
2. Format the C/C++ source file
|
||||||
``` shell
|
``` shell
|
||||||
|
|
|
@ -194,7 +194,7 @@ aot_intrinsic_clz_i32(uint32 type)
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_clz_i64(uint64 type)
|
aot_intrinsic_clz_i64(uint64 type)
|
||||||
{
|
{
|
||||||
uint32 num = 0;
|
uint32 num = 0;
|
||||||
|
@ -220,7 +220,7 @@ aot_intrinsic_ctz_i32(uint32 type)
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_ctz_i64(uint64 type)
|
aot_intrinsic_ctz_i64(uint64 type)
|
||||||
{
|
{
|
||||||
uint32 num = 0;
|
uint32 num = 0;
|
||||||
|
@ -244,7 +244,7 @@ aot_intrinsic_popcnt_i32(uint32 u)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_popcnt_i64(uint64 u)
|
aot_intrinsic_popcnt_i64(uint64 u)
|
||||||
{
|
{
|
||||||
uint32 ret = 0;
|
uint32 ret = 0;
|
||||||
|
|
|
@ -186,19 +186,19 @@ aot_intrinsic_fmax_f64(float64 a, float64 b);
|
||||||
uint32
|
uint32
|
||||||
aot_intrinsic_clz_i32(uint32 type);
|
aot_intrinsic_clz_i32(uint32 type);
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_clz_i64(uint64 type);
|
aot_intrinsic_clz_i64(uint64 type);
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
aot_intrinsic_ctz_i32(uint32 type);
|
aot_intrinsic_ctz_i32(uint32 type);
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_ctz_i64(uint64 type);
|
aot_intrinsic_ctz_i64(uint64 type);
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
aot_intrinsic_popcnt_i32(uint32 u);
|
aot_intrinsic_popcnt_i32(uint32 u);
|
||||||
|
|
||||||
uint32
|
uint64
|
||||||
aot_intrinsic_popcnt_i64(uint64 u);
|
aot_intrinsic_popcnt_i64(uint64 u);
|
||||||
|
|
||||||
float32
|
float32
|
||||||
|
|
|
@ -3189,10 +3189,12 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|
||||||
symbol_addr = module->code;
|
symbol_addr = module->code;
|
||||||
}
|
}
|
||||||
else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
|
else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
|
||||||
|| !strcmp(symbol, ".rdata")
|
|| !strcmp(symbol, ".rdata") || !strcmp(symbol, ".rodata")
|
||||||
|| !strcmp(symbol, ".rodata")
|
|| !strcmp(symbol, ".srodata")
|
||||||
/* ".rodata.cst4/8/16/.." */
|
/* ".rodata.cst4/8/16/.." */
|
||||||
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
|
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
|
||||||
|
/* ".srodata.cst4/8/16/.." */
|
||||||
|
|| !strncmp(symbol, ".srodata.cst", strlen(".srodata.cst"))
|
||||||
/* ".rodata.strn.m" */
|
/* ".rodata.strn.m" */
|
||||||
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
|
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
|
||||||
|| !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME)
|
|| !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME)
|
||||||
|
|
|
@ -999,6 +999,7 @@ static bool
|
||||||
aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
{
|
{
|
||||||
AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index];
|
AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index];
|
||||||
|
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||||
LLVMValueRef func_index_ref;
|
LLVMValueRef func_index_ref;
|
||||||
uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64;
|
uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64;
|
||||||
uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size;
|
uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size;
|
||||||
|
@ -1230,6 +1231,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
|
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
|
||||||
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false))
|
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false))
|
||||||
return false;
|
return false;
|
||||||
|
if (module->functions[func_index]->has_memory_operations)
|
||||||
|
restore_memory_info(comp_ctx, func_ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1250,6 +1253,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
|
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
|
||||||
tbl_idx))
|
tbl_idx))
|
||||||
return false;
|
return false;
|
||||||
|
if (module->functions[func_index]->has_memory_operations)
|
||||||
|
restore_memory_info(comp_ctx, func_ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1420,6 +1425,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx,
|
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx,
|
||||||
false))
|
false))
|
||||||
return false;
|
return false;
|
||||||
|
if (module->functions[func_index]->has_memory_operations)
|
||||||
|
restore_memory_info(comp_ctx, func_ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2092,6 +2099,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
||||||
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
|
||||||
if (!aot_compile_op_memory_grow(comp_ctx, func_ctx))
|
if (!aot_compile_op_memory_grow(comp_ctx, func_ctx))
|
||||||
return false;
|
return false;
|
||||||
|
if (module->functions[func_index]->has_memory_operations)
|
||||||
|
restore_memory_info(comp_ctx, func_ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WASM_OP_I32_CONST:
|
case WASM_OP_I32_CONST:
|
||||||
|
|
|
@ -648,6 +648,7 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
||||||
#define SIZE_T_TYPE comp_ctx->basic_types.size_t_type
|
#define SIZE_T_TYPE comp_ctx->basic_types.size_t_type
|
||||||
#define MD_TYPE comp_ctx->basic_types.meta_data_type
|
#define MD_TYPE comp_ctx->basic_types.meta_data_type
|
||||||
#define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type
|
#define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type
|
||||||
|
#define INT8_PPTR_TYPE comp_ctx->basic_types.int8_pptr_type
|
||||||
#define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type
|
#define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type
|
||||||
#define INT32_PTR_TYPE comp_ctx->basic_types.int32_ptr_type
|
#define INT32_PTR_TYPE comp_ctx->basic_types.int32_ptr_type
|
||||||
#define INT64_PTR_TYPE comp_ctx->basic_types.int64_ptr_type
|
#define INT64_PTR_TYPE comp_ctx->basic_types.int64_ptr_type
|
||||||
|
|
|
@ -3270,8 +3270,17 @@ is_data_section(AOTObjectData *obj_data, LLVMSectionIteratorRef sec_itr,
|
||||||
|
|
||||||
return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
|
return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
|
||||||
|| !strcmp(section_name, ".rodata")
|
|| !strcmp(section_name, ".rodata")
|
||||||
|
#if LLVM_VERSION_MAJOR >= 19
|
||||||
|
/* https://github.com/llvm/llvm-project/pull/82214 */
|
||||||
|
|| !strcmp(section_name, ".srodata")
|
||||||
|
#endif
|
||||||
/* ".rodata.cst4/8/16/.." */
|
/* ".rodata.cst4/8/16/.." */
|
||||||
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
|
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
|
||||||
|
#if LLVM_VERSION_MAJOR >= 19
|
||||||
|
/* https://github.com/llvm/llvm-project/pull/82214
|
||||||
|
* ".srodata.cst4/8/16/.." */
|
||||||
|
|| !strncmp(section_name, ".srodata.cst", strlen(".srodata.cst"))
|
||||||
|
#endif
|
||||||
/* ".rodata.strn.m" */
|
/* ".rodata.strn.m" */
|
||||||
|| !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
|
|| !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
|
||||||
|| (!strcmp(section_name, ".rdata")
|
|| (!strcmp(section_name, ".rdata")
|
||||||
|
|
|
@ -78,9 +78,6 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_ctx->mem_space_unchanged)
|
|
||||||
return mem_check_bound;
|
|
||||||
|
|
||||||
if (!(mem_check_bound = LLVMBuildLoad2(
|
if (!(mem_check_bound = LLVMBuildLoad2(
|
||||||
comp_ctx->builder,
|
comp_ctx->builder,
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE : I32_TYPE,
|
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE : I32_TYPE,
|
||||||
|
@ -164,17 +161,15 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get memory base address and memory data size */
|
/* Get memory base address and memory data size */
|
||||||
if (func_ctx->mem_space_unchanged
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|| is_shared_memory
|
if (is_shared_memory)
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
|
mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
|
||||||
}
|
else
|
||||||
else {
|
#endif
|
||||||
|
{
|
||||||
if (!(mem_base_addr = LLVMBuildLoad2(
|
if (!(mem_base_addr = LLVMBuildLoad2(
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE,
|
comp_ctx->builder, OPQ_PTR_TYPE,
|
||||||
func_ctx->mem_info[0].mem_base_addr, "mem_base"))) {
|
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
|
||||||
aot_set_last_error("llvm build load failed.");
|
aot_set_last_error("llvm build load failed.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1015,16 +1010,11 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
{
|
{
|
||||||
LLVMValueRef mem_size;
|
LLVMValueRef mem_size;
|
||||||
|
|
||||||
if (func_ctx->mem_space_unchanged) {
|
if (!(mem_size = LLVMBuildLoad2(
|
||||||
mem_size = func_ctx->mem_info[0].mem_cur_page_count_addr;
|
comp_ctx->builder, I32_TYPE,
|
||||||
}
|
func_ctx->mem_info[0].mem_cur_page_count, "mem_size"))) {
|
||||||
else {
|
aot_set_last_error("llvm build load failed.");
|
||||||
if (!(mem_size = LLVMBuildLoad2(
|
goto fail;
|
||||||
comp_ctx->builder, I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_cur_page_count_addr, "mem_size"))) {
|
|
||||||
aot_set_last_error("llvm build load failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return LLVMBuildIntCast(comp_ctx->builder, mem_size,
|
return LLVMBuildIntCast(comp_ctx->builder, mem_size,
|
||||||
|
@ -1165,16 +1155,14 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & 0x02;
|
bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & 0x02;
|
||||||
|
|
||||||
if (func_ctx->mem_space_unchanged || is_shared_memory) {
|
if (is_shared_memory)
|
||||||
#else
|
|
||||||
if (func_ctx->mem_space_unchanged) {
|
|
||||||
#endif
|
|
||||||
mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
|
mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
|
||||||
}
|
else
|
||||||
else {
|
#endif
|
||||||
|
{
|
||||||
if (!(mem_base_addr = LLVMBuildLoad2(
|
if (!(mem_base_addr = LLVMBuildLoad2(
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE,
|
comp_ctx->builder, OPQ_PTR_TYPE,
|
||||||
func_ctx->mem_info[0].mem_base_addr, "mem_base"))) {
|
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
|
||||||
aot_set_last_error("llvm build load failed.");
|
aot_set_last_error("llvm build load failed.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1206,16 +1194,11 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_ctx->mem_space_unchanged) {
|
if (!(mem_size = LLVMBuildLoad2(
|
||||||
mem_size = func_ctx->mem_info[0].mem_data_size_addr;
|
comp_ctx->builder, I64_TYPE,
|
||||||
}
|
func_ctx->mem_info[0].mem_data_size, "mem_size"))) {
|
||||||
else {
|
aot_set_last_error("llvm build load failed.");
|
||||||
if (!(mem_size = LLVMBuildLoad2(
|
goto fail;
|
||||||
comp_ctx->builder, I64_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_data_size_addr, "mem_size"))) {
|
|
||||||
aot_set_last_error("llvm build load failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_BASIC_BLOCK(check_succ, "check_succ");
|
ADD_BASIC_BLOCK(check_succ, "check_succ");
|
||||||
|
|
|
@ -1186,83 +1186,86 @@ create_local_variables(const AOTCompData *comp_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
restore_from_addr(const AOTCompContext *comp_ctx, const char *name,
|
||||||
LLVMTypeRef int8_ptr_type, uint32 func_index)
|
LLVMTypeRef type, LLVMValueRef src, LLVMValueRef dest)
|
||||||
{
|
{
|
||||||
LLVMValueRef offset, mem_info_base;
|
LLVMValueRef item;
|
||||||
uint32 memory_count;
|
if (!(item = LLVMBuildLoad2(comp_ctx->builder, type, src, name))) {
|
||||||
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
aot_set_last_error("llvm build load failed");
|
||||||
WASMFunction *func = module->functions[func_index];
|
|
||||||
LLVMTypeRef bound_check_type;
|
|
||||||
bool mem_space_unchanged =
|
|
||||||
(!func->has_op_memory_grow && !func->has_op_func_call)
|
|
||||||
|| (!module->possible_memory_grow);
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
|
||||||
bool is_shared_memory;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
func_ctx->mem_space_unchanged = mem_space_unchanged;
|
|
||||||
|
|
||||||
memory_count = module->memory_count + module->import_memory_count;
|
|
||||||
/* If the module doesn't have memory, reserve
|
|
||||||
one mem_info space with empty content */
|
|
||||||
if (memory_count == 0)
|
|
||||||
memory_count = 1;
|
|
||||||
|
|
||||||
if (!(func_ctx->mem_info =
|
|
||||||
wasm_runtime_malloc(sizeof(AOTMemInfo) * memory_count))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memset(func_ctx->mem_info, 0, sizeof(AOTMemInfo));
|
if (!LLVMBuildStore(comp_ctx->builder, item, dest)) {
|
||||||
|
aot_set_last_error("llvm build store failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Currently we only create memory info for memory 0 */
|
|
||||||
/* Load memory base address */
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
is_shared_memory =
|
static LLVMValueRef
|
||||||
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
|
aot_get_shared_mem_addr(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef offset, shared_mem_addr;
|
||||||
|
offset = I32_CONST(offsetof(AOTModuleInstance, memories));
|
||||||
|
if (!offset) {
|
||||||
|
aot_set_last_error("create llvm const failed.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* aot_inst->memories */
|
||||||
|
if (!(shared_mem_addr = LLVMBuildInBoundsGEP2(
|
||||||
|
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
||||||
|
"shared_mem_addr_offset"))) {
|
||||||
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(shared_mem_addr =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
|
||||||
|
INT8_PPTR_TYPE, "shared_mem_addr_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* aot_inst->memories[0] */
|
||||||
|
if (!(shared_mem_addr =
|
||||||
|
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
||||||
|
shared_mem_addr, "shared_mem_addr"))) {
|
||||||
|
aot_set_last_error("llvm build load failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(shared_mem_addr =
|
||||||
|
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
|
||||||
|
INT8_PPTR_TYPE, "shared_mem_addr_ptr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(shared_mem_addr =
|
||||||
|
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
||||||
|
shared_mem_addr, "shared_mem_addr"))) {
|
||||||
|
aot_set_last_error("llvm build load failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return shared_mem_addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool
|
||||||
|
restore_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||||
|
{
|
||||||
|
LLVMValueRef offset, mem_info_base, mem_base_addr_addr,
|
||||||
|
mem_cur_page_count_addr, mem_data_size_addr, bound_check_addr;
|
||||||
|
LLVMTypeRef bound_check_type, bound_check_ptr_type;
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
bool is_shared_memory =
|
||||||
|
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
|
||||||
|
|
||||||
if (is_shared_memory) {
|
if (is_shared_memory) {
|
||||||
LLVMValueRef shared_mem_addr;
|
LLVMValueRef shared_mem_addr;
|
||||||
offset = I32_CONST(offsetof(AOTModuleInstance, memories));
|
if (!(shared_mem_addr = aot_get_shared_mem_addr(comp_ctx, func_ctx)))
|
||||||
if (!offset) {
|
|
||||||
aot_set_last_error("create llvm const failed.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* aot_inst->memories */
|
|
||||||
if (!(shared_mem_addr = LLVMBuildInBoundsGEP2(
|
|
||||||
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
|
||||||
"shared_mem_addr_offset"))) {
|
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(shared_mem_addr =
|
|
||||||
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
|
|
||||||
int8_ptr_type, "shared_mem_addr_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* aot_inst->memories[0] */
|
|
||||||
if (!(shared_mem_addr =
|
|
||||||
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
|
||||||
shared_mem_addr, "shared_mem_addr"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(shared_mem_addr =
|
|
||||||
LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
|
|
||||||
int8_ptr_type, "shared_mem_addr_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(shared_mem_addr =
|
|
||||||
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
|
||||||
shared_mem_addr, "shared_mem_addr"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* memories[0]->memory_data */
|
/* memories[0]->memory_data */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data));
|
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2(
|
if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
|
||||||
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
||||||
"mem_base_addr_offset"))) {
|
"mem_base_addr_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
@ -1270,16 +1273,15 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
}
|
}
|
||||||
/* memories[0]->cur_page_count */
|
/* memories[0]->cur_page_count */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count));
|
offset = I32_CONST(offsetof(AOTMemoryInstance, cur_page_count));
|
||||||
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
|
if (!(mem_cur_page_count_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
|
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
||||||
shared_mem_addr, &offset, 1,
|
"mem_cur_page_count_offset"))) {
|
||||||
"mem_cur_page_offset"))) {
|
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* memories[0]->memory_data_size */
|
/* memories[0]->memory_data_size */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size));
|
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size));
|
||||||
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2(
|
if (!(mem_data_size_addr = LLVMBuildInBoundsGEP2(
|
||||||
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
||||||
"mem_data_size_offset"))) {
|
"mem_data_size_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
@ -1300,7 +1302,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
|
|
||||||
offset = I32_CONST(offset_of_global_table_data
|
offset = I32_CONST(offset_of_global_table_data
|
||||||
+ offsetof(AOTMemoryInstance, memory_data));
|
+ offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildInBoundsGEP2(
|
if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
|
||||||
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
||||||
"mem_base_addr_offset"))) {
|
"mem_base_addr_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
@ -1308,16 +1310,15 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
}
|
}
|
||||||
offset = I32_CONST(offset_of_global_table_data
|
offset = I32_CONST(offset_of_global_table_data
|
||||||
+ offsetof(AOTMemoryInstance, cur_page_count));
|
+ offsetof(AOTMemoryInstance, cur_page_count));
|
||||||
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
|
if (!(mem_cur_page_count_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
|
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
||||||
func_ctx->aot_inst, &offset, 1,
|
"mem_cur_page_count_offset"))) {
|
||||||
"mem_cur_page_offset"))) {
|
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
offset = I32_CONST(offset_of_global_table_data
|
offset = I32_CONST(offset_of_global_table_data
|
||||||
+ offsetof(AOTMemoryInstance, memory_data_size));
|
+ offsetof(AOTMemoryInstance, memory_data_size));
|
||||||
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildInBoundsGEP2(
|
if (!(mem_data_size_addr = LLVMBuildInBoundsGEP2(
|
||||||
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
comp_ctx->builder, INT8_TYPE, func_ctx->aot_inst, &offset, 1,
|
||||||
"mem_data_size_offset"))) {
|
"mem_data_size_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
@ -1325,196 +1326,260 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Store mem info base address before cast */
|
/* Store mem info base address before cast */
|
||||||
mem_info_base = func_ctx->mem_info[0].mem_base_addr;
|
mem_info_base = mem_base_addr_addr;
|
||||||
|
|
||||||
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildBitCast(
|
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr,
|
|
||||||
int8_ptr_type, "mem_base_addr_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = LLVMBuildBitCast(
|
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_cur_page_count_addr,
|
|
||||||
INT32_PTR_TYPE, "mem_cur_page_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildBitCast(
|
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr,
|
|
||||||
INT64_PTR_TYPE, "mem_data_size_ptr"))) {
|
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (mem_space_unchanged) {
|
|
||||||
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2(
|
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
|
|
||||||
LLVMBuildLoad2(comp_ctx->builder, I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_cur_page_count_addr,
|
|
||||||
"mem_cur_page_count"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad2(
|
|
||||||
comp_ctx->builder, I64_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_data_size_addr, "mem_data_size"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
else if (is_shared_memory) {
|
if (is_shared_memory) {
|
||||||
/* The base address for shared memory will never changed,
|
/* The base address for shared memory will never changed */
|
||||||
we can load the value here */
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad2(
|
else
|
||||||
comp_ctx->builder, OPQ_PTR_TYPE,
|
#endif
|
||||||
func_ctx->mem_info[0].mem_base_addr, "mem_base_addr"))) {
|
{
|
||||||
aot_set_last_error("llvm build load failed");
|
/* Store mem_info[0].mem_base_addr */
|
||||||
|
if (!(mem_base_addr_addr = LLVMBuildBitCast(
|
||||||
|
comp_ctx->builder, mem_base_addr_addr, INT8_PPTR_TYPE,
|
||||||
|
"mem_base_addr_addr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!restore_from_addr(
|
||||||
|
comp_ctx, "mem_base_addr", OPQ_PTR_TYPE, mem_base_addr_addr,
|
||||||
|
func_ctx->mem_info[0].mem_base_addr))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64))
|
/* Store mem_info[0].mem_cur_page_count */
|
||||||
? INT64_PTR_TYPE
|
if (!(mem_cur_page_count_addr = LLVMBuildBitCast(
|
||||||
: INT32_PTR_TYPE;
|
comp_ctx->builder, mem_cur_page_count_addr, INT32_PTR_TYPE,
|
||||||
|
"mem_cur_page_count_addr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!restore_from_addr(
|
||||||
|
comp_ctx, "mem_cur_page_count", I32_TYPE, mem_cur_page_count_addr,
|
||||||
|
func_ctx->mem_info[0].mem_cur_page_count))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Load memory bound check constants */
|
/* Store mem_info[0].mem_data_size */
|
||||||
|
if (!(mem_data_size_addr = LLVMBuildBitCast(
|
||||||
|
comp_ctx->builder, mem_data_size_addr, INT64_PTR_TYPE,
|
||||||
|
"mem_data_size_addr"))) {
|
||||||
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!restore_from_addr(
|
||||||
|
comp_ctx, "mem_data_size", I64_TYPE, mem_data_size_addr,
|
||||||
|
func_ctx->mem_info[0].mem_data_size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Store memory bound check constants */
|
||||||
|
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
||||||
|
: I32_TYPE;
|
||||||
|
bound_check_ptr_type = (comp_ctx->pointer_size == sizeof(uint64))
|
||||||
|
? INT64_PTR_TYPE
|
||||||
|
: INT32_PTR_TYPE;
|
||||||
|
|
||||||
|
/* Store mem_info[0].mem_bound_check_1byte */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte)
|
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte)
|
||||||
- offsetof(AOTMemoryInstance, memory_data));
|
- offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_1byte =
|
if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base,
|
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
||||||
&offset, 1, "bound_check_1byte_offset"))) {
|
"bound_check_1byte_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildBitCast(
|
if (!(bound_check_addr = LLVMBuildBitCast(
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_1byte,
|
comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
|
||||||
bound_check_type, "bound_check_1byte_ptr"))) {
|
"bound_check_1byte_addr"))) {
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mem_space_unchanged) {
|
if (!restore_from_addr(
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildLoad2(
|
comp_ctx, "mem_bound_check_1byte", bound_check_type,
|
||||||
comp_ctx->builder,
|
bound_check_addr, func_ctx->mem_info[0].mem_bound_check_1byte))
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
return false;
|
||||||
: I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_bound_check_1byte,
|
|
||||||
"bound_check_1byte"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Store mem_info[0].mem_bound_check_2bytes */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes)
|
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes)
|
||||||
- offsetof(AOTMemoryInstance, memory_data));
|
- offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes =
|
if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base,
|
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
||||||
&offset, 1, "bound_check_2bytes_offset"))) {
|
"bound_check_2bytes_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildBitCast(
|
if (!(bound_check_addr = LLVMBuildBitCast(
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_2bytes,
|
comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
|
||||||
bound_check_type, "bound_check_2bytes_ptr"))) {
|
"bound_check_2bytes_addr"))) {
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mem_space_unchanged) {
|
if (!restore_from_addr(
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildLoad2(
|
comp_ctx, "mem_bound_check_2bytes", bound_check_type,
|
||||||
comp_ctx->builder,
|
bound_check_addr, func_ctx->mem_info[0].mem_bound_check_2bytes))
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
return false;
|
||||||
: I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_bound_check_2bytes,
|
|
||||||
"bound_check_2bytes"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Store mem_info[0].mem_bound_check_4bytes */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes)
|
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes)
|
||||||
- offsetof(AOTMemoryInstance, memory_data));
|
- offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes =
|
if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base,
|
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
||||||
&offset, 1, "bound_check_4bytes_offset"))) {
|
"bound_check_4bytes_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildBitCast(
|
if (!(bound_check_addr = LLVMBuildBitCast(
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_4bytes,
|
comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
|
||||||
bound_check_type, "bound_check_4bytes_ptr"))) {
|
"bound_check_4bytes_addr"))) {
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mem_space_unchanged) {
|
if (!restore_from_addr(
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildLoad2(
|
comp_ctx, "mem_bound_check_4bytes", bound_check_type,
|
||||||
comp_ctx->builder,
|
bound_check_addr, func_ctx->mem_info[0].mem_bound_check_4bytes))
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
return false;
|
||||||
: I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_bound_check_4bytes,
|
|
||||||
"bound_check_4bytes"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Store mem_info[0].mem_bound_check_8bytes */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes)
|
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes)
|
||||||
- offsetof(AOTMemoryInstance, memory_data));
|
- offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes =
|
if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
|
||||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, mem_info_base,
|
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
||||||
&offset, 1, "bound_check_8bytes_offset"))) {
|
"bound_check_8bytes_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildBitCast(
|
if (!(bound_check_addr = LLVMBuildBitCast(
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_8bytes,
|
comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
|
||||||
bound_check_type, "bound_check_8bytes_ptr"))) {
|
"bound_check_8bytes_addr"))) {
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mem_space_unchanged) {
|
if (!restore_from_addr(
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildLoad2(
|
comp_ctx, "mem_bound_check_8bytes", bound_check_type,
|
||||||
comp_ctx->builder,
|
bound_check_addr, func_ctx->mem_info[0].mem_bound_check_8bytes))
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
return false;
|
||||||
: I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_bound_check_8bytes,
|
|
||||||
"bound_check_8bytes"))) {
|
|
||||||
aot_set_last_error("llvm build load failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Store mem_info[0].mem_bound_check_16bytes */
|
||||||
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes)
|
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes)
|
||||||
- offsetof(AOTMemoryInstance, memory_data));
|
- offsetof(AOTMemoryInstance, memory_data));
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildInBoundsGEP2(
|
if (!(bound_check_addr = LLVMBuildInBoundsGEP2(
|
||||||
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
comp_ctx->builder, INT8_TYPE, mem_info_base, &offset, 1,
|
||||||
"bound_check_16bytes_offset"))) {
|
"bound_check_16bytes_offset"))) {
|
||||||
aot_set_last_error("llvm build in bounds gep failed");
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildBitCast(
|
if (!(bound_check_addr = LLVMBuildBitCast(
|
||||||
comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_16bytes,
|
comp_ctx->builder, bound_check_addr, bound_check_ptr_type,
|
||||||
bound_check_type, "bound_check_16bytes_ptr"))) {
|
"bound_check_16bytes_addr"))) {
|
||||||
aot_set_last_error("llvm build bit cast failed");
|
aot_set_last_error("llvm build bit cast failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mem_space_unchanged) {
|
if (!restore_from_addr(
|
||||||
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildLoad2(
|
comp_ctx, "mem_bound_check_16bytes", bound_check_type,
|
||||||
comp_ctx->builder,
|
bound_check_addr, func_ctx->mem_info[0].mem_bound_check_16bytes))
|
||||||
(comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
return false;
|
||||||
: I32_TYPE,
|
|
||||||
func_ctx->mem_info[0].mem_bound_check_16bytes,
|
return true;
|
||||||
"bound_check_16bytes"))) {
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
|
uint32 func_index)
|
||||||
|
{
|
||||||
|
LLVMValueRef offset;
|
||||||
|
uint32 memory_count;
|
||||||
|
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||||
|
LLVMTypeRef bound_check_type;
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
bool is_shared_memory;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memory_count = module->memory_count + module->import_memory_count;
|
||||||
|
/* If the module doesn't have memory, reserve
|
||||||
|
one mem_info space with empty content */
|
||||||
|
if (memory_count == 0)
|
||||||
|
memory_count = 1;
|
||||||
|
|
||||||
|
if (!(func_ctx->mem_info =
|
||||||
|
wasm_runtime_malloc(sizeof(AOTMemInfo) * memory_count))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(func_ctx->mem_info, 0, sizeof(AOTMemInfo));
|
||||||
|
|
||||||
|
/* Currently we only create memory info for memory 0 */
|
||||||
|
/* Load memory base address */
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||||
|
is_shared_memory =
|
||||||
|
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
|
||||||
|
if (is_shared_memory) {
|
||||||
|
LLVMValueRef shared_mem_addr, mem_base_addr_addr;
|
||||||
|
if (!(shared_mem_addr = aot_get_shared_mem_addr(comp_ctx, func_ctx)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* memories[0]->memory_data */
|
||||||
|
offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data));
|
||||||
|
if (!(mem_base_addr_addr = LLVMBuildInBoundsGEP2(
|
||||||
|
comp_ctx->builder, INT8_TYPE, shared_mem_addr, &offset, 1,
|
||||||
|
"mem_base_addr_offset"))) {
|
||||||
|
aot_set_last_error("llvm build in bounds gep failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* The base address for shared memory will never changed,
|
||||||
|
we can load the value here */
|
||||||
|
if (!(func_ctx->mem_info[0].mem_base_addr =
|
||||||
|
LLVMBuildLoad2(comp_ctx->builder, OPQ_PTR_TYPE,
|
||||||
|
mem_base_addr_addr, "mem_base_addr"))) {
|
||||||
aot_set_last_error("llvm build load failed");
|
aot_set_last_error("llvm build load failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, OPQ_PTR_TYPE, "mem_base_addr"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_data_size = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, I64_TYPE, "mem_data_size"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_cur_page_count = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, I32_TYPE, "mem_cur_page_count"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) ? I64_TYPE
|
||||||
|
: I32_TYPE;
|
||||||
|
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, bound_check_type, "mem_bound_check_1byte"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, bound_check_type, "mem_bound_check_2bytes"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, bound_check_type, "mem_bound_check_4bytes"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, bound_check_type, "mem_bound_check_8bytes"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildAlloca(
|
||||||
|
comp_ctx->builder, bound_check_type, "mem_bound_check_16bytes"))) {
|
||||||
|
aot_set_last_error("llvm build alloca failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return restore_memory_info(comp_ctx, func_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1785,7 +1850,6 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||||
WASMFunction *wasm_func = module->functions[func_index];
|
WASMFunction *wasm_func = module->functions[func_index];
|
||||||
AOTBlock *aot_block;
|
AOTBlock *aot_block;
|
||||||
LLVMTypeRef int8_ptr_type;
|
|
||||||
uint64 size;
|
uint64 size;
|
||||||
|
|
||||||
/* Allocate memory for the function context */
|
/* Allocate memory for the function context */
|
||||||
|
@ -1849,14 +1913,9 @@ aot_create_func_context(const AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0))) {
|
|
||||||
aot_set_last_error("llvm add pointer type failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create base addr, end addr, data size of mem, heap */
|
/* Create base addr, end addr, data size of mem, heap */
|
||||||
if (wasm_func->has_memory_operations
|
if (wasm_func->has_memory_operations
|
||||||
&& !create_memory_info(comp_ctx, func_ctx, int8_ptr_type, func_index)) {
|
&& !create_memory_info(comp_ctx, func_ctx, func_index)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2742,10 +2801,23 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Create LLVM target machine */
|
/* Create LLVM target machine */
|
||||||
arch = option->target_arch;
|
if (!option->target_arch || !strstr(option->target_arch, "-")) {
|
||||||
abi = option->target_abi;
|
/* Retrieve the target triple based on user input */
|
||||||
cpu = option->target_cpu;
|
triple = NULL;
|
||||||
features = option->cpu_features;
|
arch = option->target_arch;
|
||||||
|
abi = option->target_abi;
|
||||||
|
cpu = option->target_cpu;
|
||||||
|
features = option->cpu_features;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Form a target triple */
|
||||||
|
triple = option->target_arch;
|
||||||
|
arch = NULL;
|
||||||
|
abi = NULL;
|
||||||
|
cpu = NULL;
|
||||||
|
features = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
opt_level = option->opt_level;
|
opt_level = option->opt_level;
|
||||||
size_level = option->size_level;
|
size_level = option->size_level;
|
||||||
|
|
||||||
|
@ -2986,6 +3058,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
aot_set_last_error(buf);
|
aot_set_last_error(buf);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
LOG_VERBOSE("triple: %s => normailized: %s", triple, triple_norm);
|
||||||
if (!cpu)
|
if (!cpu)
|
||||||
cpu = "";
|
cpu = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,8 +215,8 @@ typedef struct AOTCheckedAddr {
|
||||||
|
|
||||||
typedef struct AOTMemInfo {
|
typedef struct AOTMemInfo {
|
||||||
LLVMValueRef mem_base_addr;
|
LLVMValueRef mem_base_addr;
|
||||||
LLVMValueRef mem_data_size_addr;
|
LLVMValueRef mem_data_size;
|
||||||
LLVMValueRef mem_cur_page_count_addr;
|
LLVMValueRef mem_cur_page_count;
|
||||||
LLVMValueRef mem_bound_check_1byte;
|
LLVMValueRef mem_bound_check_1byte;
|
||||||
LLVMValueRef mem_bound_check_2bytes;
|
LLVMValueRef mem_bound_check_2bytes;
|
||||||
LLVMValueRef mem_bound_check_4bytes;
|
LLVMValueRef mem_bound_check_4bytes;
|
||||||
|
@ -251,7 +251,6 @@ typedef struct AOTFuncContext {
|
||||||
LLVMValueRef wasm_stack_top_bound;
|
LLVMValueRef wasm_stack_top_bound;
|
||||||
LLVMValueRef wasm_stack_top_ptr;
|
LLVMValueRef wasm_stack_top_ptr;
|
||||||
|
|
||||||
bool mem_space_unchanged;
|
|
||||||
AOTCheckedAddrList checked_addr_list;
|
AOTCheckedAddrList checked_addr_list;
|
||||||
|
|
||||||
LLVMValueRef shared_heap_base_addr_adj;
|
LLVMValueRef shared_heap_base_addr_adj;
|
||||||
|
@ -656,6 +655,9 @@ unsigned int
|
||||||
aot_estimate_stack_usage_for_function_call(const AOTCompContext *comp_ctx,
|
aot_estimate_stack_usage_for_function_call(const AOTCompContext *comp_ctx,
|
||||||
const AOTFuncType *callee_func_type);
|
const AOTFuncType *callee_func_type);
|
||||||
|
|
||||||
|
bool
|
||||||
|
restore_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -118,7 +118,7 @@ os_dcache_flush()
|
||||||
up_textheap_data_sync();
|
up_textheap_data_sync();
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_BUILD_KERNEL
|
#ifndef CONFIG_BUILD_KERNEL
|
||||||
up_invalidate_dcache_all();
|
up_flush_dcache_all();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,9 @@ print_help()
|
||||||
printf(" Default is host arch, e.g. x86_64\n");
|
printf(" Default is host arch, e.g. x86_64\n");
|
||||||
printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n");
|
printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n");
|
||||||
printf(" Use --target=help to list supported targets\n");
|
printf(" Use --target=help to list supported targets\n");
|
||||||
|
printf(" Or, provide a triple in the format of <arch>-<vendor>-<os>-<abi>.\n");
|
||||||
|
printf(" By doing this, --target-abi, --cpu, and --cpu-features will be ignored.\n");
|
||||||
|
printf(" The triple will only be normalized without any further verification.\n");
|
||||||
printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n");
|
printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n");
|
||||||
printf(" Default is gnu if target isn't riscv64 or riscv32\n");
|
printf(" Default is gnu if target isn't riscv64 or riscv32\n");
|
||||||
printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n");
|
printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user