Apply clang-format for core/iwasm compilation and libraries (#784)

Apply clang-format for core/iwasm/compilation and core/iwasm/libraries files.
Add wasm-c-api empty_imports sample to workflow test.
And enable triggering workflow when core/config.h changes.
This commit is contained in:
Wenyong Huang 2021-10-13 15:13:00 +08:00 committed by GitHub
parent dc65d2910a
commit fb4afc7ca4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 9321 additions and 9829 deletions

View File

@ -399,6 +399,7 @@ jobs:
cmake --build . --config Release --parallel 4 cmake --build . --config Release --parallel 4
./callback ./callback
./callback_chain ./callback_chain
./empty_imports
./global ./global
./hello ./hello
./hostref ./hostref

View File

@ -6,6 +6,7 @@ on:
# will be triggered on PR events # will be triggered on PR events
pull_request: pull_request:
paths: paths:
- "core/config.h"
- "core/iwasm/**" - "core/iwasm/**"
- "core/shared/**" - "core/shared/**"
- "wamr-compiler/**" - "wamr-compiler/**"
@ -13,6 +14,7 @@ on:
# will be triggered on push events # will be triggered on push events
push: push:
paths: paths:
- "core/config.h"
- "core/iwasm/**" - "core/iwasm/**"
- "core/shared/**" - "core/shared/**"
- "wamr-compiler/**" - "wamr-compiler/**"

View File

@ -6,6 +6,7 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
/* clang-format off */
#if !defined(BUILD_TARGET_X86_64) \ #if !defined(BUILD_TARGET_X86_64) \
&& !defined(BUILD_TARGET_AMD_64) \ && !defined(BUILD_TARGET_AMD_64) \
&& !defined(BUILD_TARGET_AARCH64) \ && !defined(BUILD_TARGET_AARCH64) \
@ -21,6 +22,7 @@
&& !defined(BUILD_TARGET_RISCV32_ILP32D) \ && !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_RISCV32_ILP32) \ && !defined(BUILD_TARGET_RISCV32_ILP32) \
&& !defined(BUILD_TARGET_ARC) && !defined(BUILD_TARGET_ARC)
/* clang-format on */
#if defined(__x86_64__) || defined(__x86_64) #if defined(__x86_64__) || defined(__x86_64)
#define BUILD_TARGET_X86_64 #define BUILD_TARGET_X86_64
#elif defined(__amd64__) || defined(__amd64) #elif defined(__amd64__) || defined(__amd64)
@ -312,4 +314,3 @@
#endif #endif
#endif /* end of _CONFIG_H_ */ #endif /* end of _CONFIG_H_ */

View File

@ -5,7 +5,6 @@
#include "aot.h" #include "aot.h"
static char aot_error[128]; static char aot_error[128];
char * char *
@ -61,8 +60,8 @@ aot_create_mem_init_data_list(const WASMModule *module)
/* Create each memory data segment */ /* Create each memory data segment */
for (i = 0; i < module->data_seg_count; i++) { for (i = 0; i < module->data_seg_count; i++) {
size = offsetof(AOTMemInitData, bytes) + size = offsetof(AOTMemInitData, bytes)
(uint64)module->data_segments[i]->data_length; + (uint64)module->data_segments[i]->data_length;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) { || !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -115,8 +114,9 @@ aot_create_table_init_data_list(const WASMModule *module)
/* Create each table data segment */ /* Create each table data segment */
for (i = 0; i < module->table_seg_count; i++) { for (i = 0; i < module->table_seg_count; i++) {
size = offsetof(AOTTableInitData, func_indexes) + size =
sizeof(uint32) * (uint64)module->table_segments[i].function_count; offsetof(AOTTableInitData, func_indexes)
+ sizeof(uint32) * (uint64)module->table_segments[i].function_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) { || !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -124,15 +124,18 @@ aot_create_table_init_data_list(const WASMModule *module)
} }
data_list[i]->offset = module->table_segments[i].base_offset; data_list[i]->offset = module->table_segments[i].base_offset;
data_list[i]->func_index_count = module->table_segments[i].function_count; data_list[i]->func_index_count =
module->table_segments[i].function_count;
data_list[i]->mode = module->table_segments[i].mode; data_list[i]->mode = module->table_segments[i].mode;
data_list[i]->elem_type = module->table_segments[i].elem_type; data_list[i]->elem_type = module->table_segments[i].elem_type;
/* runtime control it */ /* runtime control it */
data_list[i]->is_dropped = false; data_list[i]->is_dropped = false;
data_list[i]->table_index = module->table_segments[i].table_index; data_list[i]->table_index = module->table_segments[i].table_index;
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr), bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
&module->table_segments[i].base_offset, sizeof(AOTInitExpr)); &module->table_segments[i].base_offset,
data_list[i]->func_index_count = module->table_segments[i].function_count; sizeof(AOTInitExpr));
data_list[i]->func_index_count =
module->table_segments[i].function_count;
bh_memcpy_s(data_list[i]->func_indexes, bh_memcpy_s(data_list[i]->func_indexes,
sizeof(uint32) * module->table_segments[i].function_count, sizeof(uint32) * module->table_segments[i].function_count,
module->table_segments[i].func_indexes, module->table_segments[i].func_indexes,
@ -171,7 +174,8 @@ aot_create_import_globals(const WASMModule *module,
import_globals[i].global_name = import_global->field_name; import_globals[i].global_name = import_global->field_name;
import_globals[i].type = import_global->type; import_globals[i].type = import_global->type;
import_globals[i].is_mutable = import_global->is_mutable; import_globals[i].is_mutable = import_global->is_mutable;
import_globals[i].global_data_linked = import_global->global_data_linked; import_globals[i].global_data_linked =
import_global->global_data_linked;
import_globals[i].size = wasm_value_type_size(import_global->type); import_globals[i].size = wasm_value_type_size(import_global->type);
/* Calculate data offset */ /* Calculate data offset */
import_globals[i].data_offset = data_offset; import_globals[i].data_offset = data_offset;
@ -183,8 +187,7 @@ aot_create_import_globals(const WASMModule *module,
} }
static AOTGlobal * static AOTGlobal *
aot_create_globals(const WASMModule *module, aot_create_globals(const WASMModule *module, uint32 global_data_start_offset,
uint32 global_data_start_offset,
uint32 *p_global_data_size) uint32 *p_global_data_size)
{ {
AOTGlobal *globals; AOTGlobal *globals;
@ -193,8 +196,7 @@ aot_create_globals(const WASMModule *module,
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTGlobal) * (uint64)module->global_count; size = sizeof(AOTGlobal) * (uint64)module->global_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX || !(globals = wasm_runtime_malloc((uint32)size))) {
|| !(globals = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
@ -247,9 +249,9 @@ aot_create_func_types(const WASMModule *module)
/* Create each function type */ /* Create each function type */
for (i = 0; i < module->type_count; i++) { for (i = 0; i < module->type_count; i++) {
size = offsetof(AOTFuncType, types) + size = offsetof(AOTFuncType, types)
(uint64)module->types[i]->param_count + + (uint64)module->types[i]->param_count
(uint64)module->types[i]->result_count; + (uint64)module->types[i]->result_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(func_types[i] = wasm_runtime_malloc((uint32)size))) { || !(func_types[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -282,7 +284,8 @@ aot_create_import_funcs(const WASMModule *module)
/* Create each import function */ /* Create each import function */
for (i = 0; i < module->import_function_count; i++) { for (i = 0; i < module->import_function_count; i++) {
WASMFunctionImport *import_func = &module->import_functions[i].u.function; WASMFunctionImport *import_func =
&module->import_functions[i].u.function;
import_funcs[i].module_name = import_func->module_name; import_funcs[i].module_name = import_func->module_name;
import_funcs[i].func_name = import_func->field_name; import_funcs[i].func_name = import_func->field_name;
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked; import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
@ -322,8 +325,7 @@ aot_create_funcs(const WASMModule *module)
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTFunc *) * (uint64)module->function_count; size = sizeof(AOTFunc *) * (uint64)module->function_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX || !(funcs = wasm_runtime_malloc((uint32)size))) {
|| !(funcs = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
@ -379,7 +381,8 @@ aot_create_comp_data(WASMModule *module)
memset(comp_data, 0, sizeof(AOTCompData)); memset(comp_data, 0, sizeof(AOTCompData));
comp_data->memory_count = module->import_memory_count + module->memory_count; comp_data->memory_count =
module->import_memory_count + module->memory_count;
/* TODO: create import memories */ /* TODO: create import memories */
@ -415,8 +418,7 @@ aot_create_comp_data(WASMModule *module)
} }
else { else {
j = i - module->import_memory_count; j = i - module->import_memory_count;
comp_data->memories[i].memory_flags = comp_data->memories[i].memory_flags = module->memories[j].flags;
module->memories[j].flags;
comp_data->memories[i].num_bytes_per_page = comp_data->memories[i].num_bytes_per_page =
module->memories[j].num_bytes_per_page; module->memories[j].num_bytes_per_page;
comp_data->memories[i].mem_init_page_count = comp_data->memories[i].mem_init_page_count =
@ -463,9 +465,12 @@ aot_create_comp_data(WASMModule *module)
j = i - module->import_table_count; j = i - module->import_table_count;
comp_data->tables[i].elem_type = module->tables[j].elem_type; comp_data->tables[i].elem_type = module->tables[j].elem_type;
comp_data->tables[i].table_flags = module->tables[j].flags; comp_data->tables[i].table_flags = module->tables[j].flags;
comp_data->tables[i].table_init_size = module->tables[j].init_size; comp_data->tables[i].table_init_size =
comp_data->tables[i].table_max_size = module->tables[j].max_size; module->tables[j].init_size;
comp_data->tables[i].possible_grow = module->tables[j].possible_grow; comp_data->tables[i].table_max_size =
module->tables[j].max_size;
comp_data->tables[i].possible_grow =
module->tables[j].possible_grow;
} }
} }
} }
@ -487,12 +492,11 @@ aot_create_comp_data(WASMModule *module)
/* Create globals */ /* Create globals */
comp_data->global_count = module->global_count; comp_data->global_count = module->global_count;
if (comp_data->global_count if (comp_data->global_count
&& !(comp_data->globals = aot_create_globals && !(comp_data->globals = aot_create_globals(
(module, import_global_data_size, &global_data_size))) module, import_global_data_size, &global_data_size)))
goto fail; goto fail;
comp_data->global_data_size = import_global_data_size + comp_data->global_data_size = import_global_data_size + global_data_size;
global_data_size;
/* Create function types */ /* Create function types */
comp_data->func_type_count = module->type_count; comp_data->func_type_count = module->type_count;
@ -508,8 +512,7 @@ aot_create_comp_data(WASMModule *module)
/* Create functions */ /* Create functions */
comp_data->func_count = module->function_count; comp_data->func_count = module->function_count;
if (comp_data->func_count if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
&& !(comp_data->funcs = aot_create_funcs(module)))
goto fail; goto fail;
/* Create aux data/heap/stack information */ /* Create aux data/heap/stack information */
@ -580,4 +583,3 @@ aot_destroy_comp_data(AOTCompData *comp_data)
wasm_runtime_free(comp_data); wasm_runtime_free(comp_data);
} }

View File

@ -282,12 +282,14 @@ void
aot_set_last_error_v(const char *format, ...); aot_set_last_error_v(const char *format, ...);
#if BH_DEBUG != 0 #if BH_DEBUG != 0
#define HANDLE_FAILURE(callee) do { \ #define HANDLE_FAILURE(callee) \
do { \
aot_set_last_error_v("call %s failed in %s:%d", (callee), \ aot_set_last_error_v("call %s failed in %s:%d", (callee), \
__FUNCTION__, __LINE__); \ __FUNCTION__, __LINE__); \
} while (0) } while (0)
#else #else
#define HANDLE_FAILURE(callee) do { \ #define HANDLE_FAILURE(callee) \
do { \
aot_set_last_error_v("call %s failed", (callee)); \ aot_set_last_error_v("call %s failed", (callee)); \
} while (0) } while (0)
#endif #endif
@ -309,4 +311,3 @@ aot_get_imp_tbl_data_slots(const AOTImportTable *tbl)
#endif #endif
#endif /* end of _AOT_H_ */ #endif /* end of _AOT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -106,25 +106,26 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
return false; return false;
} }
#define CHECK_STACK() do { \ #define CHECK_STACK() \
do { \
if (!func_ctx->block_stack.block_list_end) { \ if (!func_ctx->block_stack.block_list_end) { \
aot_set_last_error("WASM block stack underflow."); \ aot_set_last_error("WASM block stack underflow."); \
goto fail; \ goto fail; \
} \ } \
if (!func_ctx->block_stack.block_list_end-> \ if (!func_ctx->block_stack.block_list_end->value_stack \
value_stack.value_list_end) { \ .value_list_end) { \
aot_set_last_error("WASM data stack underflow."); \ aot_set_last_error("WASM data stack underflow."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define POP(llvm_value, value_type) do { \ #define POP(llvm_value, value_type) \
do { \
AOTValue *aot_value; \ AOTValue *aot_value; \
CHECK_STACK(); \ CHECK_STACK(); \
aot_value = aot_value_stack_pop \ aot_value = aot_value_stack_pop( \
(&func_ctx->block_stack.block_list_end->value_stack); \ &func_ctx->block_stack.block_list_end->value_stack); \
if (!check_type_compatible(aot_value->type, \ if (!check_type_compatible(aot_value->type, value_type)) { \
value_type)) { \
aot_set_last_error("invalid WASM stack data type."); \ aot_set_last_error("invalid WASM stack data type."); \
wasm_runtime_free(aot_value); \ wasm_runtime_free(aot_value); \
goto fail; \ goto fail; \
@ -133,8 +134,9 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
llvm_value = aot_value->value; \ llvm_value = aot_value->value; \
else { \ else { \
if (aot_value->type == VALUE_TYPE_I1) { \ if (aot_value->type == VALUE_TYPE_I1) { \
if (!(llvm_value = LLVMBuildZExt(comp_ctx->builder, \ if (!(llvm_value = \
aot_value->value, I32_TYPE, "i1toi32"))) { \ LLVMBuildZExt(comp_ctx->builder, aot_value->value, \
I32_TYPE, "i1toi32"))) { \
aot_set_last_error("invalid WASM stack " \ aot_set_last_error("invalid WASM stack " \
"data type."); \ "data type."); \
wasm_runtime_free(aot_value); \ wasm_runtime_free(aot_value); \
@ -162,11 +164,12 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
#define POP_FUNCREF(v) POP(v, VALUE_TYPE_FUNCREF) #define POP_FUNCREF(v) POP(v, VALUE_TYPE_FUNCREF)
#define POP_EXTERNREF(v) POP(v, VALUE_TYPE_EXTERNREF) #define POP_EXTERNREF(v) POP(v, VALUE_TYPE_EXTERNREF)
#define POP_COND(llvm_value) do { \ #define POP_COND(llvm_value) \
do { \
AOTValue *aot_value; \ AOTValue *aot_value; \
CHECK_STACK(); \ CHECK_STACK(); \
aot_value = aot_value_stack_pop \ aot_value = aot_value_stack_pop( \
(&func_ctx->block_stack.block_list_end->value_stack); \ &func_ctx->block_stack.block_list_end->value_stack); \
if (aot_value->type != VALUE_TYPE_I1 \ if (aot_value->type != VALUE_TYPE_I1 \
&& aot_value->type != VALUE_TYPE_I32) { \ && aot_value->type != VALUE_TYPE_I32) { \
aot_set_last_error("invalid WASM stack data type."); \ aot_set_last_error("invalid WASM stack data type."); \
@ -176,9 +179,9 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
if (aot_value->type == VALUE_TYPE_I1) \ if (aot_value->type == VALUE_TYPE_I1) \
llvm_value = aot_value->value; \ llvm_value = aot_value->value; \
else { \ else { \
if (!(llvm_value = LLVMBuildICmp(comp_ctx->builder, \ if (!(llvm_value = \
LLVMIntNE, aot_value->value, I32_ZERO, \ LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, \
"i1_cond"))){ \ aot_value->value, I32_ZERO, "i1_cond"))) { \
aot_set_last_error("llvm build trunc failed."); \ aot_set_last_error("llvm build trunc failed."); \
wasm_runtime_free(aot_value); \ wasm_runtime_free(aot_value); \
goto fail; \ goto fail; \
@ -187,7 +190,8 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
wasm_runtime_free(aot_value); \ wasm_runtime_free(aot_value); \
} while (0) } while (0)
#define PUSH(llvm_value, value_type) do { \ #define PUSH(llvm_value, value_type) \
do { \
AOTValue *aot_value; \ AOTValue *aot_value; \
if (!func_ctx->block_stack.block_list_end) { \ if (!func_ctx->block_stack.block_list_end) { \
aot_set_last_error("WASM block stack underflow."); \ aot_set_last_error("WASM block stack underflow."); \
@ -201,9 +205,8 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
memset(aot_value, 0, sizeof(AOTValue)); \ memset(aot_value, 0, sizeof(AOTValue)); \
aot_value->type = value_type; \ aot_value->type = value_type; \
aot_value->value = llvm_value; \ aot_value->value = llvm_value; \
aot_value_stack_push \ aot_value_stack_push( \
(&func_ctx->block_stack.block_list_end->value_stack,\ &func_ctx->block_stack.block_list_end->value_stack, aot_value); \
aot_value); \
} while (0) } while (0)
#define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32) #define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32)
@ -282,29 +285,31 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
#define V128_f32x4_ZERO LLVM_CONST(f32x4_vec_zero) #define V128_f32x4_ZERO LLVM_CONST(f32x4_vec_zero)
#define V128_f64x2_ZERO LLVM_CONST(f64x2_vec_zero) #define V128_f64x2_ZERO LLVM_CONST(f64x2_vec_zero)
#define TO_V128_i8x16(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_i8x16(v) \
V128_i8x16_TYPE, "i8x16_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_i8x16_TYPE, "i8x16_val")
#define TO_V128_i16x8(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_i16x8(v) \
V128_i16x8_TYPE, "i16x8_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_i16x8_TYPE, "i16x8_val")
#define TO_V128_i32x4(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_i32x4(v) \
V128_i32x4_TYPE, "i32x4_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_i32x4_TYPE, "i32x4_val")
#define TO_V128_i64x2(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_i64x2(v) \
V128_i64x2_TYPE, "i64x2_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_i64x2_TYPE, "i64x2_val")
#define TO_V128_f32x4(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_f32x4(v) \
V128_f32x4_TYPE, "f32x4_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_f32x4_TYPE, "f32x4_val")
#define TO_V128_f64x2(v) LLVMBuildBitCast(comp_ctx->builder, v, \ #define TO_V128_f64x2(v) \
V128_f64x2_TYPE, "f64x2_val") LLVMBuildBitCast(comp_ctx->builder, v, V128_f64x2_TYPE, "f64x2_val")
#define CHECK_LLVM_CONST(v) do { \ #define CHECK_LLVM_CONST(v) \
do { \
if (!v) { \ if (!v) { \
aot_set_last_error("create llvm const failed."); \ aot_set_last_error("create llvm const failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define GET_AOT_FUNCTION(name, argc) do { \ #define GET_AOT_FUNCTION(name, argc) \
if (!(func_type = LLVMFunctionType(ret_type, param_types, \ do { \
argc, false))) { \ if (!(func_type = \
LLVMFunctionType(ret_type, param_types, argc, false))) { \
aot_set_last_error("llvm add function type failed."); \ aot_set_last_error("llvm add function type failed."); \
return false; \ return false; \
} \ } \
@ -324,8 +329,8 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
char *func_name = #name; \ char *func_name = #name; \
/* AOT mode, delcare the function */ \ /* AOT mode, delcare the function */ \
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \ if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \
&& !(func = LLVMAddFunction(comp_ctx->module, \ && !(func = LLVMAddFunction(comp_ctx->module, func_name, \
func_name, func_type))) { \ func_type))) { \
aot_set_last_error("llvm add function failed."); \ aot_set_last_error("llvm add function failed."); \
return false; \ return false; \
} \ } \
@ -339,13 +344,11 @@ bool
aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name); aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name);
bool bool
aot_emit_aot_file(AOTCompContext *comp_ctx, aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTCompData *comp_data,
const char *file_name); const char *file_name);
uint8 * uint8 *
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTCompData *comp_data,
uint32 *p_aot_file_size); uint32 *p_aot_file_size);
bool bool
@ -353,13 +356,11 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
uint8 * uint8 *
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size, aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
uint32 opt_level, uint32 size_level, uint32 opt_level, uint32 size_level, char *error_buf,
char *error_buf, uint32 error_buf_size, uint32 error_buf_size, uint32 *p_aot_file_size);
uint32 *p_aot_file_size);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif
#endif /* end of _AOT_COMPILER_H_ */ #endif /* end of _AOT_COMPILER_H_ */

View File

@ -6,14 +6,19 @@
#include "aot_compiler.h" #include "aot_compiler.h"
#include "../aot/aot_runtime.h" #include "../aot/aot_runtime.h"
#define PUT_U64_TO_ADDR(addr, value) do { \ #define PUT_U64_TO_ADDR(addr, value) \
union { uint64 val; uint32 parts[2]; } u; \ do { \
union { \
uint64 val; \
uint32 parts[2]; \
} u; \
u.val = (value); \ u.val = (value); \
((uint32 *)(addr))[0] = u.parts[0]; \ ((uint32 *)(addr))[0] = u.parts[0]; \
((uint32 *)(addr))[1] = u.parts[1]; \ ((uint32 *)(addr))[1] = u.parts[1]; \
} while (0) } while (0)
#define CHECK_SIZE(size) do { \ #define CHECK_SIZE(size) \
do { \
if (size == (uint32)-1) { \ if (size == (uint32)-1) { \
aot_set_last_error("get symbol size failed."); \ aot_set_last_error("get symbol size failed."); \
return (uint32)-1; \ return (uint32)-1; \
@ -124,8 +129,7 @@ get_mem_init_data_size(AOTMemInitData *mem_init_data)
{ {
/* init expr type (4 bytes) + init expr value (8 bytes) /* init expr type (4 bytes) + init expr value (8 bytes)
+ byte count (4 bytes) + bytes */ + byte count (4 bytes) + bytes */
uint32 total_size = uint32 total_size = (uint32)(sizeof(uint32) + sizeof(uint64)
(uint32)(sizeof(uint32) + sizeof(uint64)
+ sizeof(uint32) + mem_init_data->byte_count); + sizeof(uint32) + mem_init_data->byte_count);
/* bulk_memory enabled: /* bulk_memory enabled:
@ -173,8 +177,7 @@ get_mem_info_size(AOTCompData *comp_data)
{ {
/* import_memory_size + memory_size /* import_memory_size + memory_size
+ init_data_count + init_data_list */ + init_data_count + init_data_list */
return get_import_memory_size(comp_data) return get_import_memory_size(comp_data) + get_memory_size(comp_data)
+ get_memory_size(comp_data)
+ (uint32)sizeof(uint32) + (uint32)sizeof(uint32)
+ get_mem_init_data_list_size(comp_data->mem_init_data_list, + get_mem_init_data_list_size(comp_data->mem_init_data_list,
comp_data->mem_init_data_count); comp_data->mem_init_data_count);
@ -186,7 +189,8 @@ get_table_init_data_size(AOTTableInitData *table_init_data)
/* /*
* mode (4 bytes), elem_type (4 bytes), do not need is_dropped field * mode (4 bytes), elem_type (4 bytes), do not need is_dropped field
* *
* table_index(4 bytes) + init expr type (4 bytes) + init expr value (8 bytes) * table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
* bytes)
* + func index count (4 bytes) + func indexes * + func index count (4 bytes) + func indexes
*/ */
return (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32) return (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32)
@ -238,8 +242,7 @@ get_import_table_size(AOTCompData *comp_data)
* ------------------------------ * ------------------------------
*/ */
return (uint32)(sizeof(uint32) return (uint32)(sizeof(uint32)
+ comp_data->import_table_count + comp_data->import_table_count * (sizeof(uint32) * 3));
* (sizeof(uint32) * 3));
} }
static uint32 static uint32
@ -257,8 +260,7 @@ get_table_size(AOTCompData *comp_data)
* ------------------------------ * ------------------------------
*/ */
return (uint32)(sizeof(uint32) return (uint32)(sizeof(uint32)
+ comp_data->table_count + comp_data->table_count * (sizeof(uint32) * 5));
* (sizeof(uint32) * 5));
} }
static uint32 static uint32
@ -294,8 +296,8 @@ static uint32
get_func_type_size(AOTFuncType *func_type) get_func_type_size(AOTFuncType *func_type)
{ {
/* param count + result count + types */ /* param count + result count + types */
return (uint32)sizeof(uint32) * 2 return (uint32)sizeof(uint32) * 2 + func_type->param_count
+ func_type->param_count + func_type->result_count; + func_type->result_count;
} }
static uint32 static uint32
@ -324,8 +326,8 @@ static uint32
get_import_global_size(AOTImportGlobal *import_global) get_import_global_size(AOTImportGlobal *import_global)
{ {
/* type (1 byte) + is_mutable (1 byte) + module_name + global_name */ /* type (1 byte) + is_mutable (1 byte) + module_name + global_name */
uint32 size = (uint32)sizeof(uint8) * 2 uint32 size =
+ get_string_size(import_global->module_name); (uint32)sizeof(uint8) * 2 + get_string_size(import_global->module_name);
size = align_uint(size, 2); size = align_uint(size, 2);
size += get_string_size(import_global->global_name); size += get_string_size(import_global->global_name);
return size; return size;
@ -385,24 +387,22 @@ get_global_info_size(AOTCompData *comp_data)
{ {
/* global count + globals */ /* global count + globals */
return (uint32)sizeof(uint32) return (uint32)sizeof(uint32)
+ get_globals_size(comp_data->globals, + get_globals_size(comp_data->globals, comp_data->global_count);
comp_data->global_count);
} }
static uint32 static uint32
get_import_func_size(AOTImportFunc *import_func) get_import_func_size(AOTImportFunc *import_func)
{ {
/* type index (2 bytes) + module_name + func_name */ /* type index (2 bytes) + module_name + func_name */
uint32 size = (uint32)sizeof(uint16) uint32 size =
+ get_string_size(import_func->module_name); (uint32)sizeof(uint16) + get_string_size(import_func->module_name);
size = align_uint(size, 2); size = align_uint(size, 2);
size += get_string_size(import_func->func_name); size += get_string_size(import_func->func_name);
return size; return size;
} }
static uint32 static uint32
get_import_funcs_size(AOTImportFunc *import_funcs, get_import_funcs_size(AOTImportFunc *import_funcs, uint32 import_func_count)
uint32 import_func_count)
{ {
AOTImportFunc *import_func = import_funcs; AOTImportFunc *import_func = import_funcs;
uint32 size = 0, i; uint32 size = 0, i;
@ -493,7 +493,8 @@ get_init_data_section_size(AOTCompData *comp_data, AOTObjectData *obj_data)
static uint32 static uint32
get_text_section_size(AOTObjectData *obj_data) get_text_section_size(AOTObjectData *obj_data)
{ {
return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3) & ~3; return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3)
& ~3;
} }
static uint32 static uint32
@ -556,8 +557,7 @@ get_relocation_size(AOTRelocation *relocation, bool is_32bin)
} }
static uint32 static uint32
get_relocations_size(AOTRelocation *relocations, get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
uint32 relocation_count,
bool is_32bin) bool is_32bin)
{ {
AOTRelocation *relocation = relocations; AOTRelocation *relocation = relocations;
@ -571,23 +571,20 @@ get_relocations_size(AOTRelocation *relocations,
} }
static uint32 static uint32
get_relocation_group_size(AOTRelocationGroup *relocation_group, get_relocation_group_size(AOTRelocationGroup *relocation_group, bool is_32bin)
bool is_32bin)
{ {
uint32 size = 0; uint32 size = 0;
/* section name index + relocation count + relocations */ /* section name index + relocation count + relocations */
size += (uint32)sizeof(uint32); size += (uint32)sizeof(uint32);
size += (uint32)sizeof(uint32); size += (uint32)sizeof(uint32);
size += get_relocations_size(relocation_group->relocations, size += get_relocations_size(relocation_group->relocations,
relocation_group->relocation_count, relocation_group->relocation_count, is_32bin);
is_32bin);
return size; return size;
} }
static uint32 static uint32
get_relocation_groups_size(AOTRelocationGroup *relocation_groups, get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
uint32 relocation_group_count, uint32 relocation_group_count, bool is_32bin)
bool is_32bin)
{ {
AOTRelocationGroup *relocation_group = relocation_groups; AOTRelocationGroup *relocation_group = relocation_groups;
uint32 size = 0, i; uint32 size = 0, i;
@ -602,8 +599,7 @@ get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
/* return the index (in order of insertion) of the symbol, /* return the index (in order of insertion) of the symbol,
create if not exits, -1 if failed */ create if not exits, -1 if failed */
static uint32 static uint32
get_relocation_symbol_index(const char *symbol_name, get_relocation_symbol_index(const char *symbol_name, bool *is_new,
bool *is_new,
AOTSymbolList *symbol_list) AOTSymbolList *symbol_list)
{ {
AOTSymbolNode *sym; AOTSymbolNode *sym;
@ -652,7 +648,8 @@ get_relocation_symbol_size(AOTRelocation *relocation,
uint32 size = 0, index = 0; uint32 size = 0, index = 0;
bool is_new = false; bool is_new = false;
index = get_relocation_symbol_index(relocation->symbol_name, &is_new, symbol_list); index = get_relocation_symbol_index(relocation->symbol_name, &is_new,
symbol_list);
CHECK_SIZE(index); CHECK_SIZE(index);
if (is_new) { if (is_new) {
@ -666,8 +663,7 @@ get_relocation_symbol_size(AOTRelocation *relocation,
} }
static uint32 static uint32
get_relocations_symbol_size(AOTRelocation *relocations, get_relocations_symbol_size(AOTRelocation *relocations, uint32 relocation_count,
uint32 relocation_count,
AOTSymbolList *symbol_list) AOTSymbolList *symbol_list)
{ {
AOTRelocation *relocation = relocations; AOTRelocation *relocation = relocations;
@ -689,8 +685,7 @@ get_relocation_group_symbol_size(AOTRelocationGroup *relocation_group,
uint32 size = 0, index = 0, curr_size; uint32 size = 0, index = 0, curr_size;
bool is_new = false; bool is_new = false;
index = get_relocation_symbol_index(relocation_group->section_name, index = get_relocation_symbol_index(relocation_group->section_name, &is_new,
&is_new,
symbol_list); symbol_list);
CHECK_SIZE(index); CHECK_SIZE(index);
@ -720,8 +715,8 @@ get_relocation_groups_symbol_size(AOTRelocationGroup *relocation_groups,
uint32 size = 0, curr_size, i; uint32 size = 0, curr_size, i;
for (i = 0; i < relocation_group_count; i++, relocation_group++) { for (i = 0; i < relocation_group_count; i++, relocation_group++) {
curr_size = get_relocation_group_symbol_size(relocation_group, curr_size =
symbol_list); get_relocation_group_symbol_size(relocation_group, symbol_list);
CHECK_SIZE(curr_size); CHECK_SIZE(curr_size);
size += curr_size; size += curr_size;
} }
@ -759,15 +754,14 @@ get_relocation_section_symbol_size(AOTObjectData *obj_data)
get_symbol_size_from_symbol_list(&obj_data->symbol_list); get_symbol_size_from_symbol_list(&obj_data->symbol_list);
} }
else { else {
symbol_table_size = symbol_table_size = get_relocation_groups_symbol_size(
get_relocation_groups_symbol_size(relocation_groups, relocation_groups, relocation_group_count, &obj_data->symbol_list);
relocation_group_count,
&obj_data->symbol_list);
} }
CHECK_SIZE(symbol_table_size); CHECK_SIZE(symbol_table_size);
string_count = obj_data->symbol_list.len; string_count = obj_data->symbol_list.len;
/* string_count + string_offsets + total_string_len + [str (string_len + str)] */ /* string_count + string_offsets + total_string_len
+ [str (string_len + str)] */
return (uint32)(sizeof(uint32) + sizeof(uint32) * string_count return (uint32)(sizeof(uint32) + sizeof(uint32) * string_count
+ sizeof(uint32) + symbol_table_size); + sizeof(uint32) + symbol_table_size);
} }
@ -917,20 +911,23 @@ static union {
#define is_little_endian() (__ue.b == 1) #define is_little_endian() (__ue.b == 1)
#define CHECK_BUF(length) do { \ #define CHECK_BUF(length) \
do { \
if (buf + offset + length > buf_end) { \ if (buf + offset + length > buf_end) { \
aot_set_last_error("buf overflow"); \ aot_set_last_error("buf overflow"); \
return false; \ return false; \
} \ } \
} while (0) } while (0)
#define EMIT_U8(v) do { \ #define EMIT_U8(v) \
do { \
CHECK_BUF(1); \ CHECK_BUF(1); \
*(uint8 *)(buf + offset) = (uint8)v; \ *(uint8 *)(buf + offset) = (uint8)v; \
offset++; \ offset++; \
} while (0) } while (0)
#define EMIT_U16(v) do { \ #define EMIT_U16(v) \
do { \
uint16 t = (uint16)v; \ uint16 t = (uint16)v; \
CHECK_BUF(2); \ CHECK_BUF(2); \
if (!is_little_endian()) \ if (!is_little_endian()) \
@ -939,7 +936,8 @@ static union {
offset += (uint32)sizeof(uint16); \ offset += (uint32)sizeof(uint16); \
} while (0) } while (0)
#define EMIT_U32(v) do { \ #define EMIT_U32(v) \
do { \
uint32 t = (uint32)v; \ uint32 t = (uint32)v; \
CHECK_BUF(4); \ CHECK_BUF(4); \
if (!is_little_endian()) \ if (!is_little_endian()) \
@ -948,7 +946,8 @@ static union {
offset += (uint32)sizeof(uint32); \ offset += (uint32)sizeof(uint32); \
} while (0) } while (0)
#define EMIT_U64(v) do { \ #define EMIT_U64(v) \
do { \
uint64 t = (uint64)v; \ uint64 t = (uint64)v; \
CHECK_BUF(8); \ CHECK_BUF(8); \
if (!is_little_endian()) \ if (!is_little_endian()) \
@ -957,7 +956,8 @@ static union {
offset += (uint32)sizeof(uint64); \ offset += (uint32)sizeof(uint64); \
} while (0) } while (0)
#define EMIT_V128(v) do { \ #define EMIT_V128(v) \
do { \
uint64 *t = (uint64 *)v.i64x2; \ uint64 *t = (uint64 *)v.i64x2; \
CHECK_BUF(16); \ CHECK_BUF(16); \
if (!is_little_endian()) \ if (!is_little_endian()) \
@ -968,13 +968,15 @@ static union {
offset += (uint32)sizeof(uint64); \ offset += (uint32)sizeof(uint64); \
} while (0) } while (0)
#define EMIT_BUF(v, len) do { \ #define EMIT_BUF(v, len) \
do { \
CHECK_BUF(len); \ CHECK_BUF(len); \
memcpy(buf + offset, v, len); \ memcpy(buf + offset, v, len); \
offset += len; \ offset += len; \
} while (0) } while (0)
#define EMIT_STR(s) do { \ #define EMIT_STR(s) \
do { \
uint32 str_len = (uint32)strlen(s); \ uint32 str_len = (uint32)strlen(s); \
EMIT_U16(str_len); \ EMIT_U16(str_len); \
EMIT_BUF(s, str_len); \ EMIT_BUF(s, str_len); \
@ -1311,9 +1313,11 @@ aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
if (!aot_emit_mem_info(buf, buf_end, &offset, comp_ctx, comp_data, obj_data) if (!aot_emit_mem_info(buf, buf_end, &offset, comp_ctx, comp_data, obj_data)
|| !aot_emit_table_info(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_table_info(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_func_type_info(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_func_type_info(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_import_global_info(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_import_global_info(buf, buf_end, &offset, comp_data,
obj_data)
|| !aot_emit_global_info(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_global_info(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_import_func_info(buf, buf_end, &offset, comp_data, obj_data)) || !aot_emit_import_func_info(buf, buf_end, &offset, comp_data,
obj_data))
return false; return false;
offset = align_uint(offset, 4); offset = align_uint(offset, 4);
@ -1440,7 +1444,8 @@ aot_emit_export_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
static bool static bool
aot_emit_relocation_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *p_offset, aot_emit_relocation_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompData *comp_data, AOTObjectData *obj_data) AOTCompData *comp_data,
AOTObjectData *obj_data)
{ {
uint32 symbol_offset = 0, total_string_len = 0; uint32 symbol_offset = 0, total_string_len = 0;
uint32 offset = *p_offset; uint32 offset = *p_offset;
@ -1490,7 +1495,8 @@ aot_emit_relocation_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U32(AOT_SECTION_TYPE_RELOCATION); EMIT_U32(AOT_SECTION_TYPE_RELOCATION);
EMIT_U32(section_size); EMIT_U32(section_size);
aot_emit_relocation_symbol_table(buf, buf_end, &offset, comp_data, obj_data); aot_emit_relocation_symbol_table(buf, buf_end, &offset, comp_data,
obj_data);
offset = align_uint(offset, 4); offset = align_uint(offset, 4);
EMIT_U32(obj_data->relocation_group_count); EMIT_U32(obj_data->relocation_group_count);
@ -1655,8 +1661,8 @@ typedef struct elf64_rela {
elf64_sxword r_addend; elf64_sxword r_addend;
} elf64_rela; } elf64_rela;
#define SET_TARGET_INFO(f, v, type, little) \
#define SET_TARGET_INFO(f, v, type, little) do { \ do { \
type tmp = elf_header->v; \ type tmp = elf_header->v; \
if ((little && !is_little_endian()) \ if ((little && !is_little_endian()) \
|| (!little && is_little_endian())) \ || (!little && is_little_endian())) \
@ -1671,10 +1677,8 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
const uint8 *elf_buf = (uint8 *)LLVMGetBufferStart(obj_data->mem_buf); const uint8 *elf_buf = (uint8 *)LLVMGetBufferStart(obj_data->mem_buf);
uint32 elf_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf); uint32 elf_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf);
if (bin_type != LLVMBinaryTypeCOFF if (bin_type != LLVMBinaryTypeCOFF && bin_type != LLVMBinaryTypeELF32L
&& bin_type != LLVMBinaryTypeELF32L && bin_type != LLVMBinaryTypeELF32B && bin_type != LLVMBinaryTypeELF64L
&& bin_type != LLVMBinaryTypeELF32B
&& bin_type != LLVMBinaryTypeELF64L
&& bin_type != LLVMBinaryTypeELF64B && bin_type != LLVMBinaryTypeELF64B
&& bin_type != LLVMBinaryTypeMachO32L && bin_type != LLVMBinaryTypeMachO32L
&& bin_type != LLVMBinaryTypeMachO32B && bin_type != LLVMBinaryTypeMachO32B
@ -1747,7 +1751,6 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
return false; return false;
} }
strncpy(obj_data->target_info.arch, comp_ctx->target_arch, strncpy(obj_data->target_info.arch, comp_ctx->target_arch,
sizeof(obj_data->target_info.arch)); sizeof(obj_data->target_info.arch));
@ -1800,7 +1803,8 @@ aot_resolve_literal(AOTObjectData *obj_data)
return false; return false;
} }
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr)) && !strcmp(name, ".literal")) { if ((name = (char *)LLVMGetSectionName(sec_itr))
&& !strcmp(name, ".literal")) {
obj_data->literal = (char *)LLVMGetSectionContents(sec_itr); obj_data->literal = (char *)LLVMGetSectionContents(sec_itr);
obj_data->literal_size = (uint32)LLVMGetSectionSize(sec_itr); obj_data->literal_size = (uint32)LLVMGetSectionSize(sec_itr);
break; break;
@ -1820,8 +1824,7 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
{ {
uint32 relocation_count = 0; uint32 relocation_count = 0;
return (!strcmp(section_name, ".data") return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
|| !strcmp(section_name, ".sdata")
|| !strcmp(section_name, ".rodata") || !strcmp(section_name, ".rodata")
/* ".rodata.cst4/8/16/.." */ /* ".rodata.cst4/8/16/.." */
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst")) || !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
@ -1869,7 +1872,8 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
if (sections_count > 0) { if (sections_count > 0) {
size = (uint32)sizeof(AOTObjectDataSection) * sections_count; size = (uint32)sizeof(AOTObjectDataSection) * sections_count;
if (!(data_section = obj_data->data_sections = wasm_runtime_malloc(size))) { if (!(data_section = obj_data->data_sections =
wasm_runtime_malloc(size))) {
aot_set_last_error("allocate memory for data sections failed."); aot_set_last_error("allocate memory for data sections failed.");
return false; return false;
} }
@ -1880,7 +1884,8 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
aot_set_last_error("llvm get section iterator failed."); aot_set_last_error("llvm get section iterator failed.");
return false; return false;
} }
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { while (
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr)) if ((name = (char *)LLVMGetSectionName(sec_itr))
&& (is_data_section(sec_itr, name))) { && (is_data_section(sec_itr, name))) {
data_section->name = name; data_section->name = name;
@ -2020,14 +2025,16 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
/* parse relocation addend from reloction content */ /* parse relocation addend from reloction content */
if (has_addend) { if (has_addend) {
if (is_binary_32bit) { if (is_binary_32bit) {
uint32 addend = (uint32)(((struct elf32_rela *)rela_content)->r_addend); uint32 addend =
(uint32)(((struct elf32_rela *)rela_content)->r_addend);
if (is_binary_little_endian != is_little_endian()) if (is_binary_little_endian != is_little_endian())
exchange_uint32((uint8 *)&addend); exchange_uint32((uint8 *)&addend);
relocation->relocation_addend = (uint64)addend; relocation->relocation_addend = (uint64)addend;
rela_content += sizeof(struct elf32_rela); rela_content += sizeof(struct elf32_rela);
} }
else { else {
uint64 addend = (uint64)(((struct elf64_rela *)rela_content)->r_addend); uint64 addend =
(uint64)(((struct elf64_rela *)rela_content)->r_addend);
if (is_binary_little_endian != is_little_endian()) if (is_binary_little_endian != is_little_endian())
exchange_uint64((uint8 *)&addend); exchange_uint64((uint8 *)&addend);
relocation->relocation_addend = addend; relocation->relocation_addend = addend;
@ -2047,21 +2054,24 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
&& (str_starts_with(relocation->symbol_name, ".LCPI") && (str_starts_with(relocation->symbol_name, ".LCPI")
|| str_starts_with(relocation->symbol_name, ".LJTI") || str_starts_with(relocation->symbol_name, ".LJTI")
|| str_starts_with(relocation->symbol_name, ".LBB"))) { || str_starts_with(relocation->symbol_name, ".LBB"))) {
/* change relocation->relocation_addend and relocation->symbol_name */ /* change relocation->relocation_addend and
relocation->symbol_name */
LLVMSectionIteratorRef contain_section; LLVMSectionIteratorRef contain_section;
if (!(contain_section if (!(contain_section =
= LLVMObjectFileCopySectionIterator(obj_data->binary))) { LLVMObjectFileCopySectionIterator(obj_data->binary))) {
aot_set_last_error("llvm get section iterator failed."); aot_set_last_error("llvm get section iterator failed.");
goto fail; goto fail;
} }
LLVMMoveToContainingSection(contain_section, rel_sym); LLVMMoveToContainingSection(contain_section, rel_sym);
if (LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, contain_section)) { if (LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary,
contain_section)) {
LLVMDisposeSectionIterator(contain_section); LLVMDisposeSectionIterator(contain_section);
aot_set_last_error("llvm get containing section failed."); aot_set_last_error("llvm get containing section failed.");
goto fail; goto fail;
} }
relocation->relocation_addend += LLVMGetSymbolAddress(rel_sym); relocation->relocation_addend += LLVMGetSymbolAddress(rel_sym);
relocation->symbol_name = (char *)LLVMGetSectionName(contain_section); relocation->symbol_name =
(char *)LLVMGetSectionName(contain_section);
LLVMDisposeSectionIterator(contain_section); LLVMDisposeSectionIterator(contain_section);
} }
@ -2151,7 +2161,8 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
return true; return true;
size = (uint32)sizeof(AOTRelocationGroup) * group_count; size = (uint32)sizeof(AOTRelocationGroup) * group_count;
if (!(relocation_group = obj_data->relocation_groups = wasm_runtime_malloc(size))) { if (!(relocation_group = obj_data->relocation_groups =
wasm_runtime_malloc(size))) {
aot_set_last_error("allocate memory for relocation groups failed."); aot_set_last_error("allocate memory for relocation groups failed.");
return false; return false;
} }
@ -2167,9 +2178,7 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
if (is_relocation_section(sec_itr)) { if (is_relocation_section(sec_itr)) {
name = (char *)LLVMGetSectionName(sec_itr); name = (char *)LLVMGetSectionName(sec_itr);
relocation_group->section_name = name; relocation_group->section_name = name;
if (!aot_resolve_object_relocation_group( if (!aot_resolve_object_relocation_group(obj_data, relocation_group,
obj_data,
relocation_group,
sec_itr)) { sec_itr)) {
LLVMDisposeSectionIterator(sec_itr); LLVMDisposeSectionIterator(sec_itr);
return false; return false;
@ -2233,8 +2242,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
{ {
char *err = NULL; char *err = NULL;
AOTObjectData *obj_data; AOTObjectData *obj_data;
LLVMTargetRef target = LLVMTargetRef target = LLVMGetTargetMachineTarget(comp_ctx->target_machine);
LLVMGetTargetMachineTarget(comp_ctx->target_machine);
bh_print_time("Begin to emit object file to buffer"); bh_print_time("Begin to emit object file to buffer");
@ -2267,9 +2275,9 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine, if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
comp_ctx->module, comp_ctx->module, buf, LLVMAssemblyFile,
buf, LLVMAssemblyFile, &err)
&err) != 0) { != 0) {
if (err) { if (err) {
LLVMDisposeMessage(err); LLVMDisposeMessage(err);
err = NULL; err = NULL;
@ -2298,8 +2306,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
/* create memory buffer from object file */ /* create memory buffer from object file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf,
&obj_data->mem_buf,
&err); &err);
/* remove temp object file */ /* remove temp object file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o"); snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
@ -2315,10 +2322,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
} }
#endif /* end of defined(_WIN32) || defined(_WIN32_) */ #endif /* end of defined(_WIN32) || defined(_WIN32_) */
} }
else if (LLVMTargetMachineEmitToMemoryBuffer(comp_ctx->target_machine, else if (LLVMTargetMachineEmitToMemoryBuffer(
comp_ctx->module, comp_ctx->target_machine, comp_ctx->module, LLVMObjectFile,
LLVMObjectFile, &err, &err, &obj_data->mem_buf)
&obj_data->mem_buf) != 0) { != 0) {
if (err) { if (err) {
LLVMDisposeMessage(err); LLVMDisposeMessage(err);
err = NULL; err = NULL;
@ -2327,8 +2334,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
goto fail; goto fail;
} }
if (!(obj_data->binary = if (!(obj_data->binary = LLVMCreateBinary(obj_data->mem_buf, NULL, &err))) {
LLVMCreateBinary(obj_data->mem_buf, NULL, &err))) {
if (err) { if (err) {
LLVMDisposeMessage(err); LLVMDisposeMessage(err);
err = NULL; err = NULL;
@ -2341,8 +2347,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
/* resolve target info/text/relocations/functions */ /* resolve target info/text/relocations/functions */
if (!aot_resolve_target_info(comp_ctx, obj_data) if (!aot_resolve_target_info(comp_ctx, obj_data)
|| !aot_resolve_text(obj_data) || !aot_resolve_text(obj_data) || !aot_resolve_literal(obj_data)
|| !aot_resolve_literal(obj_data)
|| !aot_resolve_object_data_sections(obj_data) || !aot_resolve_object_data_sections(obj_data)
|| !aot_resolve_object_relocation_groups(obj_data) || !aot_resolve_object_relocation_groups(obj_data)
|| !aot_resolve_functions(comp_ctx, obj_data)) || !aot_resolve_functions(comp_ctx, obj_data))
@ -2356,8 +2361,7 @@ fail:
} }
uint8 * uint8 *
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTCompData *comp_data,
uint32 *p_aot_file_size) uint32 *p_aot_file_size)
{ {
AOTObjectData *obj_data = aot_obj_data_create(comp_ctx); AOTObjectData *obj_data = aot_obj_data_create(comp_ctx);
@ -2378,12 +2382,15 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
buf_end = buf + aot_file_size; buf_end = buf + aot_file_size;
if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data) if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_target_info_section(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_target_info_section(buf, buf_end, &offset, comp_data,
|| !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx, comp_data, obj_data) obj_data)
|| !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx,
comp_data, obj_data)
|| !aot_emit_text_section(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_text_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_func_section(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_func_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_export_section(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_export_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_relocation_section(buf, buf_end, &offset, comp_data, obj_data) || !aot_emit_relocation_section(buf, buf_end, &offset, comp_data,
obj_data)
|| !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx)) || !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx))
goto fail2; goto fail2;
@ -2420,8 +2427,8 @@ aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
bh_print_time("Begin to emit AOT file"); bh_print_time("Begin to emit AOT file");
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data, if (!(aot_file_buf =
&aot_file_size))) { aot_emit_aot_file_buf(comp_ctx, comp_data, &aot_file_size))) {
return false; return false;
} }

View File

@ -230,4 +230,3 @@ aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
fail: fail:
return false; return false;
} }

View File

@ -28,10 +28,8 @@ bool
aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
FloatCond cond); FloatCond cond);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif
#endif /* end of _AOT_EMIT_COMPARE_H_ */ #endif /* end of _AOT_EMIT_COMPARE_H_ */

View File

@ -5,7 +5,6 @@
#include "aot_emit_const.h" #include "aot_emit_const.h"
bool bool
aot_compile_op_i32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
int32 i32_const) int32 i32_const)
@ -44,18 +43,18 @@ aot_compile_op_f32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else { else {
int32 i32_const; int32 i32_const;
memcpy(&i32_const, &f32_const, sizeof(int32)); memcpy(&i32_const, &f32_const, sizeof(int32));
if (!(alloca = LLVMBuildAlloca(comp_ctx->builder, if (!(alloca =
I32_TYPE, "i32_ptr"))) { LLVMBuildAlloca(comp_ctx->builder, I32_TYPE, "i32_ptr"))) {
aot_set_last_error("llvm build alloca failed."); aot_set_last_error("llvm build alloca failed.");
return false; return false;
} }
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(comp_ctx->builder, I32_CONST((uint32)i32_const),
I32_CONST((uint32)i32_const), alloca)) { alloca)) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
return false; return false;
} }
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, alloca, F32_PTR_TYPE,
alloca, F32_PTR_TYPE, "f32_ptr"))) { "f32_ptr"))) {
aot_set_last_error("llvm build bitcast failed."); aot_set_last_error("llvm build bitcast failed.");
return false; return false;
} }
@ -85,8 +84,8 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else { else {
int64 i64_const; int64 i64_const;
memcpy(&i64_const, &f64_const, sizeof(int64)); memcpy(&i64_const, &f64_const, sizeof(int64));
if (!(alloca = LLVMBuildAlloca(comp_ctx->builder, if (!(alloca =
I64_TYPE, "i64_ptr"))) { LLVMBuildAlloca(comp_ctx->builder, I64_TYPE, "i64_ptr"))) {
aot_set_last_error("llvm build alloca failed."); aot_set_last_error("llvm build alloca failed.");
return false; return false;
} }
@ -96,8 +95,8 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
return false; return false;
} }
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, alloca, F64_PTR_TYPE,
alloca, F64_PTR_TYPE, "f64_ptr"))) { "f64_ptr"))) {
aot_set_last_error("llvm build bitcast failed."); aot_set_last_error("llvm build bitcast failed.");
return false; return false;
} }
@ -112,4 +111,3 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
fail: fail:
return false; return false;
} }

View File

@ -33,4 +33,3 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#endif #endif
#endif /* end of _AOT_EMIT_CONST_H_ */ #endif /* end of _AOT_EMIT_CONST_H_ */

View File

@ -15,30 +15,29 @@
static char *block_name_prefix[] = { "block", "loop", "if" }; static char *block_name_prefix[] = { "block", "loop", "if" };
static char *block_name_suffix[] = { "begin", "else", "end" }; static char *block_name_suffix[] = { "begin", "else", "end" };
/* clang-format off */
enum { enum {
LABEL_BEGIN = 0, LABEL_BEGIN = 0,
LABEL_ELSE, LABEL_ELSE,
LABEL_END LABEL_END
}; };
/* clang-format on */
static void static void
format_block_name(char *name, uint32 name_size, format_block_name(char *name, uint32 name_size, uint32 block_index,
uint32 block_index, uint32 label_type, uint32 label_type, uint32 label_id)
uint32 label_id)
{ {
if (label_type != LABEL_TYPE_FUNCTION) if (label_type != LABEL_TYPE_FUNCTION)
snprintf(name, name_size, "%s%d%s%s", snprintf(name, name_size, "%s%d%s%s", block_name_prefix[label_type],
block_name_prefix[label_type], block_index, block_index, "_", block_name_suffix[label_id]);
"_", block_name_suffix[label_id]);
else else
snprintf(name, name_size, "%s", "func_end"); snprintf(name, name_size, "%s", "func_end");
} }
#define CREATE_BLOCK(new_llvm_block, name) do { \ #define CREATE_BLOCK(new_llvm_block, name) \
if (!(new_llvm_block = \ do { \
LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(new_llvm_block = LLVMAppendBasicBlockInContext( \
func_ctx->func, \ comp_ctx->context, func_ctx->func, name))) { \
name))) { \
aot_set_last_error("add LLVM basic block failed."); \ aot_set_last_error("add LLVM basic block failed."); \
goto fail; \ goto fail; \
} \ } \
@ -55,16 +54,18 @@ format_block_name(char *name, uint32 name_size,
#define MOVE_BLOCK_BEFORE(llvm_block, llvm_block_before) \ #define MOVE_BLOCK_BEFORE(llvm_block, llvm_block_before) \
LLVMMoveBasicBlockBefore(llvm_block, llvm_block_before) LLVMMoveBasicBlockBefore(llvm_block, llvm_block_before)
#define BUILD_BR(llvm_block) do { \ #define BUILD_BR(llvm_block) \
do { \
if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \ if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
aot_set_last_error("llvm build br failed."); \ aot_set_last_error("llvm build br failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define BUILD_COND_BR(value_if, block_then, block_else) do {\ #define BUILD_COND_BR(value_if, block_then, block_else) \
if (!LLVMBuildCondBr(comp_ctx->builder, value_if, \ do { \
block_then, block_else)) { \ if (!LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
block_else)) { \
aot_set_last_error("llvm build cond br failed."); \ aot_set_last_error("llvm build cond br failed."); \
goto fail; \ goto fail; \
} \ } \
@ -73,7 +74,8 @@ format_block_name(char *name, uint32 name_size,
#define SET_BUILDER_POS(llvm_block) \ #define SET_BUILDER_POS(llvm_block) \
LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block) LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
#define CREATE_RESULT_VALUE_PHIS(block) do { \ #define CREATE_RESULT_VALUE_PHIS(block) \
do { \
if (block->result_count && !block->result_phis) { \ if (block->result_count && !block->result_phis) { \
uint32 i; \ uint32 i; \
uint64 size; \ uint64 size; \
@ -88,10 +90,9 @@ format_block_name(char *name, uint32 name_size,
} \ } \
SET_BUILDER_POS(block->llvm_end_block); \ SET_BUILDER_POS(block->llvm_end_block); \
for (i = 0; i < block->result_count; i++) { \ for (i = 0; i < block->result_count; i++) { \
if (!(block->result_phis[i] = \ if (!(block->result_phis[i] = LLVMBuildPhi( \
LLVMBuildPhi(comp_ctx->builder, \ comp_ctx->builder, \
TO_LLVM_TYPE(block->result_types[i]), \ TO_LLVM_TYPE(block->result_types[i]), "phi"))) { \
"phi"))) { \
aot_set_last_error("llvm build phi failed."); \ aot_set_last_error("llvm build phi failed."); \
goto fail; \ goto fail; \
} \ } \
@ -100,30 +101,31 @@ format_block_name(char *name, uint32 name_size,
} \ } \
} while (0) } while (0)
#define ADD_TO_RESULT_PHIS(block, value, idx) do { \ #define ADD_TO_RESULT_PHIS(block, value, idx) \
do { \
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \ LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \ LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
LLVMTypeRef value_ty = LLVMTypeOf(value); \ LLVMTypeRef value_ty = LLVMTypeOf(value); \
bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \ bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
bh_assert(LLVMGetTypeContext(phi_ty) \ bh_assert(LLVMGetTypeContext(phi_ty) == LLVMGetTypeContext(value_ty)); \
== LLVMGetTypeContext(value_ty)); \
LLVMAddIncoming(block->result_phis[idx], &value, &block_curr, 1); \ LLVMAddIncoming(block->result_phis[idx], &value, &block_curr, 1); \
(void)phi_ty; \ (void)phi_ty; \
(void)value_ty; \ (void)value_ty; \
} while (0) } while (0)
#define BUILD_ICMP(op, left, right, res, name) do { \ #define BUILD_ICMP(op, left, right, res, name) \
if (!(res = LLVMBuildICmp(comp_ctx->builder, op, \ do { \
left, right, name))) { \ if (!(res = \
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
aot_set_last_error("llvm build icmp failed."); \ aot_set_last_error("llvm build icmp failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define ADD_TO_PARAM_PHIS(block, value, idx) do { \ #define ADD_TO_PARAM_PHIS(block, value, idx) \
do { \
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \ LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
LLVMAddIncoming(block->param_phis[idx], \ LLVMAddIncoming(block->param_phis[idx], &value, &block_curr, 1); \
&value, &block_curr, 1); \
} while (0) } while (0)
static LLVMBasicBlockRef static LLVMBasicBlockRef
@ -153,8 +155,7 @@ get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
} }
static bool static bool
handle_next_reachable_block(AOTCompContext *comp_ctx, handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 **p_frame_ip) uint8 **p_frame_ip)
{ {
AOTBlock *block = func_ctx->block_stack.block_list_end; AOTBlock *block = func_ctx->block_stack.block_list_end;
@ -173,11 +174,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
return_location = dwarf_gen_location( return_location = dwarf_gen_location(
comp_ctx, func_ctx, comp_ctx, func_ctx,
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
);
#endif #endif
if (block->label_type == LABEL_TYPE_IF if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
&& block->llvm_else_block
&& *p_frame_ip <= block->wasm_code_else) { && *p_frame_ip <= block->wasm_code_else) {
/* Clear value stack and start to translate else branch */ /* Clear value stack and start to translate else branch */
aot_value_stack_destroy(&block->value_stack); aot_value_stack_destroy(&block->value_stack);
@ -194,8 +193,7 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
block = aot_block_stack_pop(&func_ctx->block_stack); block = aot_block_stack_pop(&func_ctx->block_stack);
if (block->label_type == LABEL_TYPE_IF) { if (block->label_type == LABEL_TYPE_IF) {
if (block->llvm_else_block if (block->llvm_else_block && !block->skip_wasm_code_else
&& !block->skip_wasm_code_else
&& *p_frame_ip <= block->wasm_code_else) { && *p_frame_ip <= block->wasm_code_else) {
/* Clear value stack and start to translate else branch */ /* Clear value stack and start to translate else branch */
aot_value_stack_destroy(&block->value_stack); aot_value_stack_destroy(&block->value_stack);
@ -237,8 +235,8 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
/* Store extra return values to function parameters */ /* Store extra return values to function parameters */
if (i != 0) { if (i != 0) {
uint32 param_index = func_type->param_count + i; uint32 param_index = func_type->param_count + i;
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(
block->result_phis[i], comp_ctx->builder, block->result_phis[i],
LLVMGetParam(func_ctx->func, param_index))) { LLVMGetParam(func_ctx->func, param_index))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
goto fail; goto fail;
@ -293,8 +291,7 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
return false; return false;
} }
if (block->label_type == LABEL_TYPE_IF if (block->label_type == LABEL_TYPE_IF && !block->skip_wasm_code_else
&& !block->skip_wasm_code_else
&& !(block->else_param_phis = wasm_runtime_malloc((uint32)size))) { && !(block->else_param_phis = wasm_runtime_malloc((uint32)size))) {
wasm_runtime_free(block->param_phis); wasm_runtime_free(block->param_phis);
block->param_phis = NULL; block->param_phis = NULL;
@ -306,27 +303,24 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
for (i = 0; i < block->param_count; i++) { for (i = 0; i < block->param_count; i++) {
SET_BUILDER_POS(block->llvm_entry_block); SET_BUILDER_POS(block->llvm_entry_block);
snprintf(name, sizeof(name), "%s%d_phi%d", snprintf(name, sizeof(name), "%s%d_phi%d",
block_name_prefix[block->label_type], block_name_prefix[block->label_type], block->block_index,
block->block_index, i); i);
if (!(block->param_phis[i] = if (!(block->param_phis[i] = LLVMBuildPhi(
LLVMBuildPhi(comp_ctx->builder, comp_ctx->builder, TO_LLVM_TYPE(block->param_types[i]),
TO_LLVM_TYPE(block->param_types[i]),
name))) { name))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi failed.");
goto fail; goto fail;
} }
if (block->label_type == LABEL_TYPE_IF if (block->label_type == LABEL_TYPE_IF
&& !block->skip_wasm_code_else && !block->skip_wasm_code_else && block->llvm_else_block) {
&& block->llvm_else_block) {
/* Build else param phis */ /* Build else param phis */
SET_BUILDER_POS(block->llvm_else_block); SET_BUILDER_POS(block->llvm_else_block);
snprintf(name, sizeof(name), "else%d_phi%d", snprintf(name, sizeof(name), "else%d_phi%d", block->block_index,
block->block_index, i); i);
if (!(block->else_param_phis[i] = if (!(block->else_param_phis[i] = LLVMBuildPhi(
LLVMBuildPhi(comp_ctx->builder, comp_ctx->builder,
TO_LLVM_TYPE(block->param_types[i]), TO_LLVM_TYPE(block->param_types[i]), name))) {
name))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi failed.");
goto fail; goto fail;
} }
@ -345,8 +339,8 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
&& !block->skip_wasm_code_else) { && !block->skip_wasm_code_else) {
if (block->llvm_else_block) { if (block->llvm_else_block) {
/* has else branch, add to else param phis */ /* has else branch, add to else param phis */
LLVMAddIncoming(block->else_param_phis[param_index], LLVMAddIncoming(block->else_param_phis[param_index], &value,
&value, &block_curr, 1); &block_curr, 1);
} }
else { else {
/* no else branch, add to result phis */ /* no else branch, add to result phis */
@ -381,8 +375,8 @@ fail:
bool bool
aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 **p_frame_ip, uint8 *frame_ip_end, uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
uint32 label_type, uint32 param_count, uint8 *param_types, uint32 param_count, uint8 *param_types,
uint32 result_count, uint8 *result_types) uint32 result_count, uint8 *result_types)
{ {
BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE]; BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
@ -400,9 +394,9 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
memset(block_addr_cache, 0, sizeof(block_addr_cache)); memset(block_addr_cache, 0, sizeof(block_addr_cache));
/* Get block info */ /* Get block info */
if (!(wasm_loader_find_block_addr(NULL, (BlockAddr*)block_addr_cache, if (!(wasm_loader_find_block_addr(
*p_frame_ip, frame_ip_end, (uint8)label_type, NULL, (BlockAddr *)block_addr_cache, *p_frame_ip, frame_ip_end,
&else_addr, &end_addr))) { (uint8)label_type, &else_addr, &end_addr))) {
aot_set_last_error("find block end addr failed."); aot_set_last_error("find block end addr failed.");
return false; return false;
} }
@ -436,11 +430,10 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
block->block_index = func_ctx->block_stack.block_index[label_type]; block->block_index = func_ctx->block_stack.block_index[label_type];
func_ctx->block_stack.block_index[label_type]++; func_ctx->block_stack.block_index[label_type]++;
if (label_type == LABEL_TYPE_BLOCK if (label_type == LABEL_TYPE_BLOCK || label_type == LABEL_TYPE_LOOP) {
|| label_type == LABEL_TYPE_LOOP) {
/* Create block */ /* Create block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index, label_type,
block->block_index, label_type, LABEL_BEGIN); LABEL_BEGIN);
CREATE_BLOCK(block->llvm_entry_block, name); CREATE_BLOCK(block->llvm_entry_block, name);
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block); MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
/* Jump to the entry block */ /* Jump to the entry block */
@ -471,23 +464,24 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (!LLVMIsConstant(value)) { if (!LLVMIsConstant(value)) {
/* Compare value is not constant, create condition br IR */ /* Compare value is not constant, create condition br IR */
/* Create entry block */ /* Create entry block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, label_type, LABEL_BEGIN); label_type, LABEL_BEGIN);
CREATE_BLOCK(block->llvm_entry_block, name); CREATE_BLOCK(block->llvm_entry_block, name);
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block); MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
/* Create end block */ /* Create end block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, label_type, LABEL_END); label_type, LABEL_END);
CREATE_BLOCK(block->llvm_end_block, name); CREATE_BLOCK(block->llvm_end_block, name);
MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_entry_block); MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_entry_block);
if (else_addr) { if (else_addr) {
/* Create else block */ /* Create else block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, label_type, LABEL_ELSE); label_type, LABEL_ELSE);
CREATE_BLOCK(block->llvm_else_block, name); CREATE_BLOCK(block->llvm_else_block, name);
MOVE_BLOCK_AFTER(block->llvm_else_block, block->llvm_entry_block); MOVE_BLOCK_AFTER(block->llvm_else_block,
block->llvm_entry_block);
/* Create condition br IR */ /* Create condition br IR */
BUILD_COND_BR(value, block->llvm_entry_block, BUILD_COND_BR(value, block->llvm_entry_block,
block->llvm_else_block); block->llvm_else_block);
@ -498,7 +492,8 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
block->llvm_end_block); block->llvm_end_block);
block->is_reachable = true; block->is_reachable = true;
} }
if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx, block)) if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
block))
goto fail; goto fail;
/* Start to translate if branch of BLOCK if */ /* Start to translate if branch of BLOCK if */
SET_BUILDER_POS(block->llvm_entry_block); SET_BUILDER_POS(block->llvm_entry_block);
@ -509,13 +504,14 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
BLOCK if cannot be reached */ BLOCK if cannot be reached */
block->skip_wasm_code_else = true; block->skip_wasm_code_else = true;
/* Create entry block */ /* Create entry block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, label_type, LABEL_BEGIN); label_type, LABEL_BEGIN);
CREATE_BLOCK(block->llvm_entry_block, name); CREATE_BLOCK(block->llvm_entry_block, name);
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block); MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
/* Jump to the entry block */ /* Jump to the entry block */
BUILD_BR(block->llvm_entry_block); BUILD_BR(block->llvm_entry_block);
if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx, block)) if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx,
block))
goto fail; goto fail;
/* Start to translate the if branch */ /* Start to translate the if branch */
SET_BUILDER_POS(block->llvm_entry_block); SET_BUILDER_POS(block->llvm_entry_block);
@ -525,13 +521,14 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
BLOCK if cannot be reached */ BLOCK if cannot be reached */
if (else_addr) { if (else_addr) {
/* Create else block */ /* Create else block */
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, label_type, LABEL_ELSE); label_type, LABEL_ELSE);
CREATE_BLOCK(block->llvm_else_block, name); CREATE_BLOCK(block->llvm_else_block, name);
MOVE_BLOCK_AFTER_CURR(block->llvm_else_block); MOVE_BLOCK_AFTER_CURR(block->llvm_else_block);
/* Jump to the else block */ /* Jump to the else block */
BUILD_BR(block->llvm_else_block); BUILD_BR(block->llvm_else_block);
if (!push_aot_block_to_stack_and_pass_params(comp_ctx, func_ctx, block)) if (!push_aot_block_to_stack_and_pass_params(
comp_ctx, func_ctx, block))
goto fail; goto fail;
/* Start to translate the else branch */ /* Start to translate the else branch */
SET_BUILDER_POS(block->llvm_else_block); SET_BUILDER_POS(block->llvm_else_block);
@ -571,16 +568,15 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
if (block->label_type != LABEL_TYPE_IF if (block->label_type != LABEL_TYPE_IF
|| (!block->skip_wasm_code_else || (!block->skip_wasm_code_else && !block->llvm_else_block)) {
&& !block->llvm_else_block)) {
aot_set_last_error("Invalid WASM block type."); aot_set_last_error("Invalid WASM block type.");
return false; return false;
} }
/* Create end block if needed */ /* Create end block if needed */
if (!block->llvm_end_block) { if (!block->llvm_end_block) {
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, block->label_type, LABEL_END); block->label_type, LABEL_END);
CREATE_BLOCK(block->llvm_end_block, name); CREATE_BLOCK(block->llvm_end_block, name);
if (block->llvm_else_block) if (block->llvm_else_block)
MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_else_block); MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_else_block);
@ -601,8 +597,7 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Jump to end block */ /* Jump to end block */
BUILD_BR(block->llvm_end_block); BUILD_BR(block->llvm_end_block);
if (!block->skip_wasm_code_else if (!block->skip_wasm_code_else && block->llvm_else_block) {
&& block->llvm_else_block) {
/* Clear value stack, recover param values /* Clear value stack, recover param values
* and start to translate else branch. * and start to translate else branch.
*/ */
@ -639,8 +634,8 @@ aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Create the end block */ /* Create the end block */
if (!block->llvm_end_block) { if (!block->llvm_end_block) {
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block->block_index,
block->block_index, block->label_type, LABEL_END); block->label_type, LABEL_END);
CREATE_BLOCK(block->llvm_end_block, name); CREATE_BLOCK(block->llvm_end_block, name);
if ((next_llvm_end_block = find_next_llvm_end_block(block))) if ((next_llvm_end_block = find_next_llvm_end_block(block)))
MOVE_BLOCK_BEFORE(block->llvm_end_block, next_llvm_end_block); MOVE_BLOCK_BEFORE(block->llvm_end_block, next_llvm_end_block);
@ -684,16 +679,14 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
return false; return false;
} }
if (!(terminate_addr = if (!(terminate_addr =
LLVMBuildBitCast(comp_ctx->builder, LLVMBuildBitCast(comp_ctx->builder, terminate_addr,
terminate_addr,
INT32_PTR_TYPE, "terminate_addr_ptr"))) { INT32_PTR_TYPE, "terminate_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!(terminate_flags = if (!(terminate_flags = LLVMBuildLoad(comp_ctx->builder, terminate_addr,
LLVMBuildLoad(comp_ctx->builder, "terminate_flags"))) {
terminate_addr, "terminate_flags"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
@ -716,9 +709,8 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
CREATE_BLOCK(terminate_block, "terminate"); CREATE_BLOCK(terminate_block, "terminate");
MOVE_BLOCK_AFTER_CURR(terminate_block); MOVE_BLOCK_AFTER_CURR(terminate_block);
if (!(flag = if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE,
LLVMBuildAnd(comp_ctx->builder, terminate_flags, "termination_flag"))) {
I32_ONE, "termination_flag"))) {
aot_set_last_error("llvm build AND failed"); aot_set_last_error("llvm build AND failed");
return false; return false;
} }
@ -777,9 +769,8 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Dest block is Block/If/Function block */ /* Dest block is Block/If/Function block */
/* Create the end block */ /* Create the end block */
if (!block_dst->llvm_end_block) { if (!block_dst->llvm_end_block) {
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block_dst->block_index,
block_dst->block_index, block_dst->label_type, block_dst->label_type, LABEL_END);
LABEL_END);
CREATE_BLOCK(block_dst->llvm_end_block, name); CREATE_BLOCK(block_dst->llvm_end_block, name);
if ((next_llvm_end_block = find_next_llvm_end_block(block_dst))) if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
MOVE_BLOCK_BEFORE(block_dst->llvm_end_block, MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
@ -880,9 +871,8 @@ aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Dest block is Block/If/Function block */ /* Dest block is Block/If/Function block */
/* Create the end block */ /* Create the end block */
if (!block_dst->llvm_end_block) { if (!block_dst->llvm_end_block) {
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name), block_dst->block_index,
block_dst->block_index, block_dst->label_type, block_dst->label_type, LABEL_END);
LABEL_END);
CREATE_BLOCK(block_dst->llvm_end_block, name); CREATE_BLOCK(block_dst->llvm_end_block, name);
if ((next_llvm_end_block = find_next_llvm_end_block(block_dst))) if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
MOVE_BLOCK_BEFORE(block_dst->llvm_end_block, MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
@ -941,8 +931,7 @@ fail:
bool bool
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 *br_depths, uint32 br_count, uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip)
uint8 **p_frame_ip)
{ {
uint32 i, j; uint32 i, j;
LLVMValueRef value_switch, value_cmp, value_case, value, *values = NULL; LLVMValueRef value_switch, value_cmp, value_case, value, *values = NULL;
@ -989,8 +978,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (!target_block->llvm_end_block) { if (!target_block->llvm_end_block) {
format_block_name(name, sizeof(name), format_block_name(name, sizeof(name),
target_block->block_index, target_block->block_index,
target_block->label_type, target_block->label_type, LABEL_END);
LABEL_END);
CREATE_BLOCK(target_block->llvm_end_block, name); CREATE_BLOCK(target_block->llvm_end_block, name);
if ((next_llvm_end_block = if ((next_llvm_end_block =
find_next_llvm_end_block(target_block))) find_next_llvm_end_block(target_block)))
@ -999,7 +987,8 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Handle result values */ /* Handle result values */
if (target_block->result_count) { if (target_block->result_count) {
size = sizeof(LLVMValueRef) * (uint64)target_block->result_count; size = sizeof(LLVMValueRef)
* (uint64)target_block->result_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(values = wasm_runtime_malloc((uint32)size))) { || !(values = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -1024,7 +1013,8 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else { else {
/* Handle Loop parameters */ /* Handle Loop parameters */
if (target_block->param_count) { if (target_block->param_count) {
size = sizeof(LLVMValueRef) * (uint64)target_block->param_count; size = sizeof(LLVMValueRef)
* (uint64)target_block->param_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(values = wasm_runtime_malloc((uint32)size))) { || !(values = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -1102,8 +1092,7 @@ aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
return_location = dwarf_gen_location( return_location = dwarf_gen_location(
comp_ctx, func_ctx, comp_ctx, func_ctx,
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code (*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
);
#endif #endif
if (block_func->result_count) { if (block_func->result_count) {
/* Store extra result values to function parameters */ /* Store extra result values to function parameters */
@ -1111,8 +1100,7 @@ aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
result_index = block_func->result_count - 1 - i; result_index = block_func->result_count - 1 - i;
POP(value, block_func->result_types[result_index]); POP(value, block_func->result_types[result_index]);
param_index = func_type->param_count + result_index; param_index = func_type->param_count + result_index;
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(comp_ctx->builder, value,
value,
LLVMGetParam(func_ctx->func, param_index))) { LLVMGetParam(func_ctx->func, param_index))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
goto fail; goto fail;
@ -1144,12 +1132,11 @@ fail:
} }
bool bool
aot_compile_op_unreachable(AOTCompContext *comp_ctx, aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 **p_frame_ip) uint8 **p_frame_ip)
{ {
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE, if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE, false, NULL,
false, NULL, NULL)) NULL))
return false; return false;
return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
@ -1157,8 +1144,7 @@ aot_compile_op_unreachable(AOTCompContext *comp_ctx,
bool bool
aot_handle_next_reachable_block(AOTCompContext *comp_ctx, aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 **p_frame_ip)
uint8 **p_frame_ip)
{ {
return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
} }

View File

@ -14,8 +14,8 @@ extern "C" {
bool bool
aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 **p_frame_ip, uint8 *frame_ip_end, uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
uint32 label_type, uint32 param_count, uint8 *param_types, uint32 param_count, uint8 *param_types,
uint32 result_count, uint8 *result_types); uint32 result_count, uint8 *result_types);
bool bool
@ -36,22 +36,19 @@ aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool bool
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 *br_depths, uint32 br_count, uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip);
uint8 **p_frame_ip);
bool bool
aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 **p_frame_ip); uint8 **p_frame_ip);
bool bool
aot_compile_op_unreachable(AOTCompContext *comp_ctx, aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 **p_frame_ip); uint8 **p_frame_ip);
bool bool
aot_handle_next_reachable_block(AOTCompContext *comp_ctx, aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 **p_frame_ip);
uint8 **p_frame_ip);
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
bool bool
@ -63,4 +60,3 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
#endif #endif
#endif /* end of _AOT_EMIT_CONTROL_H_ */ #endif /* end of _AOT_EMIT_CONTROL_H_ */

View File

@ -11,9 +11,9 @@
static bool static bool
trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef operand, LLVMTypeRef src_type, LLVMTypeRef dest_type, LLVMValueRef operand, LLVMTypeRef src_type,
LLVMValueRef min_value, LLVMValueRef max_value, LLVMTypeRef dest_type, LLVMValueRef min_value,
char *name, bool sign) LLVMValueRef max_value, char *name, bool sign)
{ {
LLVMBasicBlockRef check_nan_succ, check_overflow_succ; LLVMBasicBlockRef check_nan_succ, check_overflow_succ;
LLVMValueRef is_less, is_greater, res; LLVMValueRef is_less, is_greater, res;
@ -44,10 +44,8 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!(check_nan_succ = if (!(check_nan_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "check_nan_succ"))) {
func_ctx->func,
"check_nan_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
} }
@ -55,8 +53,9 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_nan_succ, LLVMMoveBasicBlockAfter(check_nan_succ,
LLVMGetInsertBlock(comp_ctx->builder)); LLVMGetInsertBlock(comp_ctx->builder));
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INVALID_CONVERSION_TO_INTEGER, if (!(aot_emit_exception(comp_ctx, func_ctx,
true, res, check_nan_succ))) EXCE_INVALID_CONVERSION_TO_INTEGER, true, res,
check_nan_succ)))
goto fail; goto fail;
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
@ -113,16 +112,15 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!(res = LLVMBuildOr(comp_ctx->builder, is_less, is_greater, "is_overflow"))) { if (!(res = LLVMBuildOr(comp_ctx->builder, is_less, is_greater,
"is_overflow"))) {
aot_set_last_error("llvm build logic and failed."); aot_set_last_error("llvm build logic and failed.");
goto fail; goto fail;
} }
/* Check if float value out of range */ /* Check if float value out of range */
if (!(check_overflow_succ = if (!(check_overflow_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "check_overflow_succ"))) {
func_ctx->func,
"check_overflow_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
} }
@ -130,8 +128,8 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_overflow_succ, LLVMMoveBasicBlockAfter(check_overflow_succ,
LLVMGetInsertBlock(comp_ctx->builder)); LLVMGetInsertBlock(comp_ctx->builder));
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW, if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW, true,
true, res, check_overflow_succ))) res, check_overflow_succ)))
goto fail; goto fail;
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
@ -162,10 +160,10 @@ fail:
return false; return false;
} }
#define ADD_BASIC_BLOCK(block, name) do { \ #define ADD_BASIC_BLOCK(block, name) \
do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \ func_ctx->func, name))) { \
name))) { \
aot_set_last_error("llvm add basic block failed."); \ aot_set_last_error("llvm add basic block failed."); \
goto fail; \ goto fail; \
} \ } \
@ -175,9 +173,9 @@ fail:
static bool static bool
trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef operand, LLVMTypeRef src_type, LLVMTypeRef dest_type, LLVMValueRef operand, LLVMTypeRef src_type,
LLVMValueRef min_value, LLVMValueRef max_value, LLVMTypeRef dest_type, LLVMValueRef min_value,
char *name, bool sign) LLVMValueRef max_value, char *name, bool sign)
{ {
LLVMBasicBlockRef check_nan_succ, check_less_succ, check_greater_succ; LLVMBasicBlockRef check_nan_succ, check_less_succ, check_greater_succ;
LLVMBasicBlockRef is_nan_block, is_less_block, is_greater_block, res_block; LLVMBasicBlockRef is_nan_block, is_less_block, is_greater_block, res_block;
@ -185,8 +183,8 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef zero = (dest_type == I32_TYPE) ? I32_ZERO : I64_ZERO; LLVMValueRef zero = (dest_type == I32_TYPE) ? I32_ZERO : I64_ZERO;
LLVMValueRef vmin, vmax; LLVMValueRef vmin, vmax;
if (!(res = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, if (!(res = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, operand, operand,
operand, operand, "fcmp_is_nan"))) { "fcmp_is_nan"))) {
aot_set_last_error("llvm build fcmp failed."); aot_set_last_error("llvm build fcmp failed.");
goto fail; goto fail;
} }
@ -199,8 +197,8 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ADD_BASIC_BLOCK(is_greater_block, "is_greater_block"); ADD_BASIC_BLOCK(is_greater_block, "is_greater_block");
ADD_BASIC_BLOCK(res_block, "res_block"); ADD_BASIC_BLOCK(res_block, "res_block");
if (!LLVMBuildCondBr(comp_ctx->builder, res, if (!LLVMBuildCondBr(comp_ctx->builder, res, is_nan_block,
is_nan_block, check_nan_succ)) { check_nan_succ)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -219,8 +217,8 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build fcmp failed."); aot_set_last_error("llvm build fcmp failed.");
goto fail; goto fail;
} }
if (!LLVMBuildCondBr(comp_ctx->builder, is_less, if (!LLVMBuildCondBr(comp_ctx->builder, is_less, is_less_block,
is_less_block, check_less_succ)) { check_less_succ)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -239,8 +237,8 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build fcmp failed."); aot_set_last_error("llvm build fcmp failed.");
goto fail; goto fail;
} }
if (!LLVMBuildCondBr(comp_ctx->builder, is_greater, if (!LLVMBuildCondBr(comp_ctx->builder, is_greater, is_greater_block,
is_greater_block, check_greater_succ)) { check_greater_succ)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -281,8 +279,7 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Start to translate res_block */ /* Start to translate res_block */
LLVMPositionBuilderAtEnd(comp_ctx->builder, res_block); LLVMPositionBuilderAtEnd(comp_ctx->builder, res_block);
/* Create result phi */ /* Create result phi */
if (!(phi = LLVMBuildPhi(comp_ctx->builder, if (!(phi = LLVMBuildPhi(comp_ctx->builder, dest_type,
dest_type,
"trunc_sat_result_phi"))) { "trunc_sat_result_phi"))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi failed.");
return false; return false;
@ -330,7 +327,8 @@ aot_compile_op_i32_wrap_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
POP_I64(value); POP_I64(value);
if (!(res = LLVMBuildTrunc(comp_ctx->builder, value, I32_TYPE, "i32_wrap_i64"))) { if (!(res = LLVMBuildTrunc(comp_ctx->builder, value, I32_TYPE,
"i32_wrap_i64"))) {
aot_set_last_error("llvm build conversion failed."); aot_set_last_error("llvm build conversion failed.");
return false; return false;
} }
@ -360,14 +358,13 @@ aot_compile_op_i32_trunc_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
if (!saturating) if (!saturating)
return trunc_float_to_int(comp_ctx, func_ctx, value, return trunc_float_to_int(
F32_TYPE, I32_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F32_TYPE, I32_TYPE, min_value, max_value,
sign ? "i32_trunc_f32_s" : "i32_trunc_f32_u", sign); sign ? "i32_trunc_f32_s" : "i32_trunc_f32_u", sign);
else else
return trunc_sat_float_to_int(comp_ctx, func_ctx, value, return trunc_sat_float_to_int(
F32_TYPE, I32_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F32_TYPE, I32_TYPE, min_value, max_value,
sign ? "i32_trunc_sat_f32_s" : sign ? "i32_trunc_sat_f32_s" : "i32_trunc_sat_f32_u", sign);
"i32_trunc_sat_f32_u", sign);
fail: fail:
return false; return false;
} }
@ -391,30 +388,31 @@ aot_compile_op_i32_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
if (!saturating) if (!saturating)
return trunc_float_to_int(comp_ctx, func_ctx, value, return trunc_float_to_int(
F64_TYPE, I32_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F64_TYPE, I32_TYPE, min_value, max_value,
sign ? "i32_trunc_f64_s" : "i32_trunc_f64_u", sign); sign ? "i32_trunc_f64_s" : "i32_trunc_f64_u", sign);
else else
return trunc_sat_float_to_int(comp_ctx, func_ctx, value, return trunc_sat_float_to_int(
F64_TYPE, I32_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F64_TYPE, I32_TYPE, min_value, max_value,
sign ? "i32_trunc_sat_f64_s" : sign ? "i32_trunc_sat_f64_s" : "i32_trunc_sat_f64_u", sign);
"i32_trunc_sat_f64_u", sign);
fail: fail:
return false; return false;
} }
bool bool
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx,
bool sign) AOTFuncContext *func_ctx, bool sign)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
POP_I32(value); POP_I32(value);
if (sign) if (sign)
res = LLVMBuildSExt(comp_ctx->builder, value, I64_TYPE, "i64_extend_i32_s"); res = LLVMBuildSExt(comp_ctx->builder, value, I64_TYPE,
"i64_extend_i32_s");
else else
res = LLVMBuildZExt(comp_ctx->builder, value, I64_TYPE, "i64_extend_i32_u"); res = LLVMBuildZExt(comp_ctx->builder, value, I64_TYPE,
"i64_extend_i32_u");
if (!res) { if (!res) {
aot_set_last_error("llvm build conversion failed."); aot_set_last_error("llvm build conversion failed.");
return false; return false;
@ -427,24 +425,24 @@ fail:
} }
bool bool
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx,
int8 bitwidth) AOTFuncContext *func_ctx, int8 bitwidth)
{ {
LLVMValueRef value, res, cast_value = NULL; LLVMValueRef value, res, cast_value = NULL;
POP_I64(value); POP_I64(value);
if (bitwidth == 8) { if (bitwidth == 8) {
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT8_TYPE,
INT8_TYPE, true, "i8_intcast_i64"); true, "i8_intcast_i64");
} }
else if (bitwidth == 16) { else if (bitwidth == 16) {
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT16_TYPE,
INT16_TYPE, true, "i16_intcast_i64"); true, "i16_intcast_i64");
} }
else if (bitwidth == 32) { else if (bitwidth == 32) {
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, I32_TYPE, true,
I32_TYPE, true, "i32_intcast_i64"); "i32_intcast_i64");
} }
if (!cast_value) { if (!cast_value) {
@ -452,7 +450,8 @@ aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx
return false; return false;
} }
res = LLVMBuildSExt(comp_ctx->builder, cast_value, I64_TYPE, "i64_extend_i64_s"); res = LLVMBuildSExt(comp_ctx->builder, cast_value, I64_TYPE,
"i64_extend_i64_s");
if (!res) { if (!res) {
aot_set_last_error("llvm build conversion failed."); aot_set_last_error("llvm build conversion failed.");
@ -466,20 +465,20 @@ fail:
} }
bool bool
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx,
int8 bitwidth) AOTFuncContext *func_ctx, int8 bitwidth)
{ {
LLVMValueRef value, res, cast_value = NULL; LLVMValueRef value, res, cast_value = NULL;
POP_I32(value); POP_I32(value);
if (bitwidth == 8) { if (bitwidth == 8) {
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT8_TYPE,
INT8_TYPE, true, "i8_intcast_i32"); true, "i8_intcast_i32");
} }
else if (bitwidth == 16) { else if (bitwidth == 16) {
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT16_TYPE,
INT16_TYPE, true, "i16_intcast_i32"); true, "i16_intcast_i32");
} }
if (!cast_value) { if (!cast_value) {
@ -487,7 +486,8 @@ aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx
return false; return false;
} }
res = LLVMBuildSExt(comp_ctx->builder, cast_value, I32_TYPE, "i32_extend_i32_s"); res = LLVMBuildSExt(comp_ctx->builder, cast_value, I32_TYPE,
"i32_extend_i32_s");
if (!res) { if (!res) {
aot_set_last_error("llvm build conversion failed."); aot_set_last_error("llvm build conversion failed.");
@ -519,14 +519,13 @@ aot_compile_op_i64_trunc_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
if (!saturating) if (!saturating)
return trunc_float_to_int(comp_ctx, func_ctx, value, return trunc_float_to_int(
F32_TYPE, I64_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F32_TYPE, I64_TYPE, min_value, max_value,
sign ? "i64_trunc_f32_s" : "i64_trunc_f32_u", sign); sign ? "i64_trunc_f32_s" : "i64_trunc_f32_u", sign);
else else
return trunc_sat_float_to_int(comp_ctx, func_ctx, value, return trunc_sat_float_to_int(
F32_TYPE, I64_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F32_TYPE, I64_TYPE, min_value, max_value,
sign ? "i64_trunc_sat_f32_s" : sign ? "i64_trunc_sat_f32_s" : "i64_trunc_sat_f32_u", sign);
"i64_trunc_sat_f32_u", sign);
fail: fail:
return false; return false;
} }
@ -550,22 +549,21 @@ aot_compile_op_i64_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
if (!saturating) if (!saturating)
return trunc_float_to_int(comp_ctx, func_ctx, value, return trunc_float_to_int(
F64_TYPE, I64_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F64_TYPE, I64_TYPE, min_value, max_value,
sign ? "i64_trunc_f64_s" : "i64_trunc_f64_u", sign); sign ? "i64_trunc_f64_s" : "i64_trunc_f64_u", sign);
else else
return trunc_sat_float_to_int(comp_ctx, func_ctx, value, return trunc_sat_float_to_int(
F64_TYPE, I64_TYPE, min_value, max_value, comp_ctx, func_ctx, value, F64_TYPE, I64_TYPE, min_value, max_value,
sign ? "i64_trunc_sat_f64_s" : sign ? "i64_trunc_sat_f64_s" : "i64_trunc_sat_f64_u", sign);
"i64_trunc_sat_f64_u", sign);
fail: fail:
return false; return false;
} }
bool bool
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx,
bool sign) AOTFuncContext *func_ctx, bool sign)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -576,8 +574,9 @@ aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
comp_ctx, sign ? "f32_convert_i32_s" : "f32_convert_i32_u")) { comp_ctx, sign ? "f32_convert_i32_s" : "f32_convert_i32_u")) {
LLVMTypeRef param_types[1]; LLVMTypeRef param_types[1];
param_types[0] = I32_TYPE; param_types[0] = I32_TYPE;
res = aot_call_llvm_intrinsic( res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
comp_ctx, func_ctx, sign ? "f32_convert_i32_s" : "f32_convert_i32_u", sign ? "f32_convert_i32_s"
: "f32_convert_i32_u",
F32_TYPE, param_types, 1, value); F32_TYPE, param_types, 1, value);
} }
else { else {
@ -600,8 +599,8 @@ fail:
} }
bool bool
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx,
bool sign) AOTFuncContext *func_ctx, bool sign)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -612,8 +611,9 @@ aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
comp_ctx, sign ? "f32_convert_i64_s" : "f32_convert_i64_u")) { comp_ctx, sign ? "f32_convert_i64_s" : "f32_convert_i64_u")) {
LLVMTypeRef param_types[1]; LLVMTypeRef param_types[1];
param_types[0] = I64_TYPE; param_types[0] = I64_TYPE;
res = aot_call_llvm_intrinsic( res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
comp_ctx, func_ctx, sign ? "f32_convert_i64_s" : "f32_convert_i64_u", sign ? "f32_convert_i64_s"
: "f32_convert_i64_u",
F32_TYPE, param_types, 1, value); F32_TYPE, param_types, 1, value);
} }
else { else {
@ -637,7 +637,8 @@ fail:
} }
bool bool
aot_compile_op_f32_demote_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_op_f32_demote_f64(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -667,8 +668,8 @@ fail:
} }
bool bool
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx,
bool sign) AOTFuncContext *func_ctx, bool sign)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -680,8 +681,9 @@ aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
LLVMTypeRef param_types[1]; LLVMTypeRef param_types[1];
param_types[0] = I32_TYPE; param_types[0] = I32_TYPE;
res = aot_call_llvm_intrinsic( res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
comp_ctx, func_ctx, sign ? "f64_convert_i32_s" : "f64_convert_i32_u", sign ? "f64_convert_i32_s"
: "f64_convert_i32_u",
F64_TYPE, param_types, 1, value); F64_TYPE, param_types, 1, value);
} }
else { else {
@ -705,8 +707,8 @@ fail:
} }
bool bool
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx,
bool sign) AOTFuncContext *func_ctx, bool sign)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -718,8 +720,9 @@ aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
LLVMTypeRef param_types[1]; LLVMTypeRef param_types[1];
param_types[0] = I64_TYPE; param_types[0] = I64_TYPE;
res = aot_call_llvm_intrinsic( res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
comp_ctx, func_ctx, sign ? "f64_convert_i64_s" : "f64_convert_i64_u", sign ? "f64_convert_i64_s"
: "f64_convert_i64_u",
F64_TYPE, param_types, 1, value); F64_TYPE, param_types, 1, value);
} }
else { else {
@ -743,7 +746,8 @@ fail:
} }
bool bool
aot_compile_op_f64_promote_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_op_f64_promote_f32(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx)
{ {
LLVMValueRef value, res; LLVMValueRef value, res;
@ -781,8 +785,8 @@ aot_compile_op_i64_reinterpret_f64(AOTCompContext *comp_ctx,
{ {
LLVMValueRef value; LLVMValueRef value;
POP_F64(value); POP_F64(value);
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value, if (!(value =
I64_TYPE, "i64"))) { LLVMBuildBitCast(comp_ctx->builder, value, I64_TYPE, "i64"))) {
aot_set_last_error("llvm build fp to si failed."); aot_set_last_error("llvm build fp to si failed.");
return false; return false;
} }
@ -792,15 +796,14 @@ fail:
return false; return false;
} }
bool bool
aot_compile_op_i32_reinterpret_f32(AOTCompContext *comp_ctx, aot_compile_op_i32_reinterpret_f32(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx) AOTFuncContext *func_ctx)
{ {
LLVMValueRef value; LLVMValueRef value;
POP_F32(value); POP_F32(value);
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value, if (!(value =
I32_TYPE, "i32"))) { LLVMBuildBitCast(comp_ctx->builder, value, I32_TYPE, "i32"))) {
aot_set_last_error("llvm build fp to si failed."); aot_set_last_error("llvm build fp to si failed.");
return false; return false;
} }
@ -816,8 +819,8 @@ aot_compile_op_f64_reinterpret_i64(AOTCompContext *comp_ctx,
{ {
LLVMValueRef value; LLVMValueRef value;
POP_I64(value); POP_I64(value);
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value, if (!(value =
F64_TYPE, "f64"))) { LLVMBuildBitCast(comp_ctx->builder, value, F64_TYPE, "f64"))) {
aot_set_last_error("llvm build si to fp failed."); aot_set_last_error("llvm build si to fp failed.");
return false; return false;
} }
@ -833,8 +836,8 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
{ {
LLVMValueRef value; LLVMValueRef value;
POP_I32(value); POP_I32(value);
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value, if (!(value =
F32_TYPE, "f32"))) { LLVMBuildBitCast(comp_ctx->builder, value, F32_TYPE, "f32"))) {
aot_set_last_error("llvm build si to fp failed."); aot_set_last_error("llvm build si to fp failed.");
return false; return false;
} }
@ -843,4 +846,3 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
fail: fail:
return false; return false;
} }

View File

@ -24,16 +24,16 @@ aot_compile_op_i32_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool sign, bool saturating); bool sign, bool saturating);
bool bool
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx,
bool sign); AOTFuncContext *func_ctx, bool sign);
bool bool
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx,
int8 bitwidth); AOTFuncContext *func_ctx, int8 bitwidth);
bool bool
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx,
int8 bitwidth); AOTFuncContext *func_ctx, int8 bitwidth);
bool bool
aot_compile_op_i64_trunc_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_trunc_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -44,26 +44,28 @@ aot_compile_op_i64_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool sign, bool saturating); bool sign, bool saturating);
bool bool
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx,
bool sign); AOTFuncContext *func_ctx, bool sign);
bool bool
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx,
bool sign); AOTFuncContext *func_ctx, bool sign);
bool bool
aot_compile_op_f32_demote_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_op_f32_demote_f64(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx);
bool bool
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx,
bool sign); AOTFuncContext *func_ctx, bool sign);
bool bool
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx,
bool sign); AOTFuncContext *func_ctx, bool sign);
bool bool
aot_compile_op_f64_promote_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_op_f64_promote_f32(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx);
bool bool
aot_compile_op_i64_reinterpret_f64(AOTCompContext *comp_ctx, aot_compile_op_i64_reinterpret_f64(AOTCompContext *comp_ctx,
@ -86,4 +88,3 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
#endif #endif
#endif /* end of _AOT_EMIT_CONVERSION_H_ */ #endif /* end of _AOT_EMIT_CONVERSION_H_ */

View File

@ -8,9 +8,7 @@
bool bool
aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
int32 exception_id, int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
bool is_cond_br,
LLVMValueRef cond_br_if,
LLVMBasicBlockRef cond_br_else_block) LLVMBasicBlockRef cond_br_else_block)
{ {
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
@ -24,10 +22,8 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Create got_exception block if needed */ /* Create got_exception block if needed */
if (!func_ctx->got_exception_block) { if (!func_ctx->got_exception_block) {
if (!(func_ctx->got_exception_block = if (!(func_ctx->got_exception_block = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "got_exception"))) {
func_ctx->func,
"got_exception"))) {
aot_set_last_error("add LLVM basic block failed."); aot_set_last_error("add LLVM basic block failed.");
return false; return false;
} }
@ -48,8 +44,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ret_type = VOID_TYPE; ret_type = VOID_TYPE;
/* Create function type */ /* Create function type */
if (!(func_type = LLVMFunctionType(ret_type, param_types, if (!(func_type = LLVMFunctionType(ret_type, param_types, 2, false))) {
2, false))) {
aot_set_last_error("create LLVM function type failed."); aot_set_last_error("create LLVM function type failed.");
return false; return false;
} }
@ -101,8 +96,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Call the aot_set_exception_with_id() function */ /* Call the aot_set_exception_with_id() function */
param_values[0] = func_ctx->aot_inst; param_values[0] = func_ctx->aot_inst;
param_values[1] = func_ctx->exception_id_phi; param_values[1] = func_ctx->exception_id_phi;
if (!LLVMBuildCall(comp_ctx->builder, func, param_values, if (!LLVMBuildCall(comp_ctx->builder, func, param_values, 2, "")) {
2, "")) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -130,7 +124,8 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else { else {
/* Create condition br */ /* Create condition br */
if (!LLVMBuildCondBr(comp_ctx->builder, cond_br_if, if (!LLVMBuildCondBr(comp_ctx->builder, cond_br_if,
func_ctx->got_exception_block, cond_br_else_block)) { func_ctx->got_exception_block,
cond_br_else_block)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
return false; return false;
} }
@ -142,4 +137,3 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
fail: fail:
return false; return false;
} }

View File

@ -14,9 +14,7 @@ extern "C" {
bool bool
aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
int32 exception_id, int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
bool is_cond_br,
LLVMValueRef cond_br_if,
LLVMBasicBlockRef cond_br_else_block); LLVMBasicBlockRef cond_br_else_block);
#ifdef __cplusplus #ifdef __cplusplus
@ -24,4 +22,3 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#endif #endif
#endif /* end of _AOT_EMIT_EXCEPTION_H_ */ #endif /* end of _AOT_EMIT_EXCEPTION_H_ */

View File

@ -9,10 +9,10 @@
#include "aot_emit_table.h" #include "aot_emit_table.h"
#include "../aot/aot_runtime.h" #include "../aot/aot_runtime.h"
#define ADD_BASIC_BLOCK(block, name) do { \ #define ADD_BASIC_BLOCK(block, name) \
do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \ func_ctx->func, name))) { \
name))) { \
aot_set_last_error("llvm add basic block failed."); \ aot_set_last_error("llvm add basic block failed."); \
goto fail; \ goto fail; \
} \ } \
@ -26,15 +26,15 @@ create_func_return_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
/* Create function return block if it isn't created */ /* Create function return block if it isn't created */
if (!func_ctx->func_return_block) { if (!func_ctx->func_return_block) {
if (!(func_ctx->func_return_block = if (!(func_ctx->func_return_block = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "func_ret"))) {
func_ctx->func, "func_ret"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
} }
/* Create return IR */ /* Create return IR */
LLVMPositionBuilderAtEnd(comp_ctx->builder, func_ctx->func_return_block); LLVMPositionBuilderAtEnd(comp_ctx->builder,
func_ctx->func_return_block);
if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) { if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
return false; return false;
} }
@ -59,16 +59,15 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
whether it is '\0'. If yes, no exception was thrown. */ whether it is '\0'. If yes, no exception was thrown. */
if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->cur_exception, if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->cur_exception,
"exce_value")) "exce_value"))
|| !(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, || !(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, value, I8_ZERO,
value, I8_ZERO, "cmp"))) { "cmp"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
/* Add check exection success block */ /* Add check exection success block */
if (!(check_exce_succ = LLVMAppendBasicBlockInContext(comp_ctx->context, if (!(check_exce_succ = LLVMAppendBasicBlockInContext(
func_ctx->func, comp_ctx->context, func_ctx->func, "check_exce_succ"))) {
"check_exce_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
} }
@ -78,8 +77,8 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr); LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr);
/* Create condition br */ /* Create condition br */
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, if (!LLVMBuildCondBr(comp_ctx->builder, cmp, check_exce_succ,
check_exce_succ, func_ctx->func_return_block)) { func_ctx->func_return_block)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
return false; return false;
} }
@ -100,16 +99,15 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (!create_func_return_block(comp_ctx, func_ctx)) if (!create_func_return_block(comp_ctx, func_ctx))
return false; return false;
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, res, I8_ZERO,
res, I8_ZERO, "cmp"))) { "cmp"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
/* Add check exection success block */ /* Add check exection success block */
if (!(check_call_succ = LLVMAppendBasicBlockInContext(comp_ctx->context, if (!(check_call_succ = LLVMAppendBasicBlockInContext(
func_ctx->func, comp_ctx->context, func_ctx->func, "check_call_succ"))) {
"check_call_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
} }
@ -119,8 +117,8 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr); LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr);
/* Create condition br */ /* Create condition br */
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, if (!LLVMBuildCondBr(comp_ctx->builder, cmp, check_call_succ,
check_call_succ, func_ctx->func_return_block)) { func_ctx->func_return_block)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
return false; return false;
} }
@ -132,10 +130,11 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
static bool static bool
call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef func_idx, AOTFuncType *aot_func_type, LLVMValueRef func_idx, AOTFuncType *aot_func_type,
LLVMTypeRef *param_types, LLVMValueRef *param_values, LLVMTypeRef *param_types,
uint32 param_count, uint32 param_cell_num, LLVMValueRef *param_values, uint32 param_count,
LLVMTypeRef ret_type, uint8 wasm_ret_type, uint32 param_cell_num, LLVMTypeRef ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res) uint8 wasm_ret_type, LLVMValueRef *p_value_ret,
LLVMValueRef *p_res)
{ {
LLVMTypeRef func_type, func_ptr_type, func_param_types[4]; LLVMTypeRef func_type, func_ptr_type, func_param_types[4];
LLVMTypeRef ret_ptr_type, elem_ptr_type; LLVMTypeRef ret_ptr_type, elem_ptr_type;
@ -149,7 +148,8 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
func_param_types[1] = I32_TYPE; /* func_idx */ func_param_types[1] = I32_TYPE; /* func_idx */
func_param_types[2] = I32_TYPE; /* argc */ func_param_types[2] = I32_TYPE; /* argc */
func_param_types[3] = INT32_PTR_TYPE; /* argv */ func_param_types[3] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) { if (!(func_type =
LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
aot_set_last_error("llvm add function type failed."); aot_set_last_error("llvm add function type failed.");
return false; return false;
} }
@ -174,8 +174,7 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("create LLVM function type failed."); aot_set_last_error("create LLVM function type failed.");
return false; return false;
} }
func_index = func_index = aot_get_native_symbol_index(comp_ctx, func_name);
aot_get_native_symbol_index(comp_ctx, func_name);
if (func_index < 0) { if (func_index < 0) {
return false; return false;
} }
@ -208,15 +207,16 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
snprintf(buf, sizeof(buf), "%s%d", "elem", i); snprintf(buf, sizeof(buf), "%s%d", "elem", i);
if (!(elem_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(elem_ptr = LLVMBuildInBoundsGEP(
func_ctx->argv_buf, &elem_idx, 1, buf)) comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf))
|| !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr, || !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr,
elem_ptr_type, buf))) { elem_ptr_type, buf))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
if (!(res = LLVMBuildStore(comp_ctx->builder, param_values[i], elem_ptr))) { if (!(res = LLVMBuildStore(comp_ctx->builder, param_values[i],
elem_ptr))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
return false; return false;
} }
@ -236,8 +236,8 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* call aot_invoke_native() function */ /* call aot_invoke_native() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func, if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 4,
func_param_values, 4, "res"))) { "res"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -249,13 +249,14 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
if (!(value_ret = LLVMBuildBitCast(comp_ctx->builder, func_ctx->argv_buf, if (!(value_ret =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->argv_buf,
ret_ptr_type, "argv_ret"))) { ret_ptr_type, "argv_ret"))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, if (!(*p_value_ret =
"value_ret"))) { LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
} }
@ -285,15 +286,14 @@ call_aot_alloc_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_values[0] = func_ctx->exec_env; param_values[0] = func_ctx->exec_env;
param_values[1] = func_idx; param_values[1] = func_idx;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
param_values, 2,
"call_aot_alloc_frame"))) { "call_aot_alloc_frame"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
if (!(ret_value = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, if (!(ret_value = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, ret_value,
ret_value, I8_ZERO, "frame_alloc_ret"))) { I8_ZERO, "frame_alloc_ret"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
@ -304,8 +304,8 @@ call_aot_alloc_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(frame_alloc_fail, block_curr); LLVMMoveBasicBlockAfter(frame_alloc_fail, block_curr);
LLVMMoveBasicBlockAfter(frame_alloc_success, block_curr); LLVMMoveBasicBlockAfter(frame_alloc_success, block_curr);
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, frame_alloc_success,
frame_alloc_success, frame_alloc_fail)) { frame_alloc_fail)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
return false; return false;
} }
@ -338,8 +338,7 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
param_values[0] = func_ctx->exec_env; param_values[0] = func_ctx->exec_env;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 1,
param_values, 1,
"call_aot_free_frame"))) { "call_aot_free_frame"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
@ -347,7 +346,7 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
return true; return true;
} }
#endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) #endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) \
|| (WASM_ENABLE_PERF_PROFILING != 0) */ || (WASM_ENABLE_PERF_PROFILING != 0) */
static bool static bool
@ -363,17 +362,15 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
if (!(stack_bound = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(stack_bound = LLVMBuildInBoundsGEP(
func_ctx->native_stack_bound, comp_ctx->builder, func_ctx->native_stack_bound,
&callee_local_size, 1, &callee_local_size, 1, "stack_bound"))) {
"stack_bound"))) {
aot_set_last_error("llvm build inbound gep failed."); aot_set_last_error("llvm build inbound gep failed.");
return false; return false;
} }
if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context, if (!(check_stack = LLVMAppendBasicBlockInContext(
func_ctx->func, comp_ctx->context, func_ctx->func, "check_stack"))) {
"check_stack"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
} }
@ -381,14 +378,12 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_stack, block_curr); LLVMMoveBasicBlockAfter(check_stack, block_curr);
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT,
func_ctx->last_alloca, stack_bound, func_ctx->last_alloca, stack_bound, "cmp"))) {
"cmp"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_NATIVE_STACK_OVERFLOW,
EXCE_NATIVE_STACK_OVERFLOW,
true, cmp, check_stack)) { true, cmp, check_stack)) {
return false; return false;
} }
@ -439,8 +434,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (func_idx < import_func_count) if (func_idx < import_func_count)
func_type = import_funcs[func_idx].func_type; func_type = import_funcs[func_idx].func_type;
else else
func_type = func_ctxes[func_idx - import_func_count]-> func_type =
aot_func->func_type; func_ctxes[func_idx - import_func_count]->aot_func->func_type;
/* Get param cell number */ /* Get param cell number */
param_cell_num = func_type->param_cell_num; param_cell_num = func_type->param_cell_num;
@ -467,8 +462,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_count = (int32)func_type->param_count; param_count = (int32)func_type->param_count;
result_count = (int32)func_type->result_count; result_count = (int32)func_type->result_count;
ext_ret_count = result_count > 1 ? result_count - 1 : 0; ext_ret_count = result_count > 1 ? result_count - 1 : 0;
total_size = sizeof(LLVMValueRef) * (uint64)(param_count + 1 total_size =
+ ext_ret_count); sizeof(LLVMValueRef) * (uint64)(param_count + 1 + ext_ret_count);
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
|| !(param_values = wasm_runtime_malloc((uint32)total_size))) { || !(param_values = wasm_runtime_malloc((uint32)total_size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -511,9 +506,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i); snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i);
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ext_ret_ptr,
ext_ret_ptr, ext_ret_ptr_type, ext_ret_ptr_type, buf))) {
buf))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
goto fail; goto fail;
} }
@ -552,13 +546,14 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* call aot_invoke_native() */ /* call aot_invoke_native() */
if (!call_aot_invoke_native_func(comp_ctx, func_ctx, import_func_idx, func_type, if (!call_aot_invoke_native_func(
param_types + 1, param_values + 1, comp_ctx, func_ctx, import_func_idx, func_type, param_types + 1,
param_count, param_cell_num, param_values + 1, param_count, param_cell_num, ret_type,
ret_type, wasm_ret_type, &value_ret, &res)) wasm_ret_type, &value_ret, &res))
goto fail; goto fail;
/* Check whether there was exception thrown when executing the function */ /* Check whether there was exception thrown when executing
the function */
if (!check_call_return(comp_ctx, func_ctx, res)) if (!check_call_return(comp_ctx, func_ctx, res))
goto fail; goto fail;
} }
@ -567,7 +562,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef func_ptr_type; LLVMTypeRef func_ptr_type;
if (!(func_ptr_type = LLVMPointerType( if (!(func_ptr_type = LLVMPointerType(
func_ctxes[func_idx - import_func_count]->func_type, 0))) { func_ctxes[func_idx - import_func_count]->func_type,
0))) {
aot_set_last_error("construct func ptr type failed."); aot_set_last_error("construct func ptr type failed.");
goto fail; goto fail;
} }
@ -580,31 +576,32 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
func = func_ctxes[func_idx - import_func_count]->func; func = func_ctxes[func_idx - import_func_count]->func;
} }
aot_func = func_ctxes[func_idx - import_func_count]->aot_func; aot_func = func_ctxes[func_idx - import_func_count]->aot_func;
callee_cell_num = aot_func->param_cell_num + aot_func->local_cell_num + 1; callee_cell_num =
aot_func->param_cell_num + aot_func->local_cell_num + 1;
if (comp_ctx->enable_bound_check if (comp_ctx->enable_bound_check
&& !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num)) && !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num))
goto fail; goto fail;
/* Call the function */ /* Call the function */
if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func, if (!(value_ret =
param_values, LLVMBuildCall(comp_ctx->builder, func, param_values,
(uint32)param_count + 1 + ext_ret_count, (uint32)param_count + 1 + ext_ret_count,
(func_type->result_count > 0 (func_type->result_count > 0 ? "call" : "")))) {
? "call" : "")))) {
aot_set_last_error("LLVM build call failed."); aot_set_last_error("LLVM build call failed.");
goto fail; goto fail;
} }
/* Set calling convention for the call with the func's calling convention */ /* Set calling convention for the call with the func's calling
convention */
LLVMSetInstructionCallConv(value_ret, LLVMGetFunctionCallConv(func)); LLVMSetInstructionCallConv(value_ret, LLVMGetFunctionCallConv(func));
if (tail_call) if (tail_call)
LLVMSetTailCall(value_ret, true); LLVMSetTailCall(value_ret, true);
/* Check whether there was exception thrown when executing the function */ /* Check whether there was exception thrown when executing
if (!tail_call the function */
&& !check_exception_thrown(comp_ctx, func_ctx)) if (!tail_call && !check_exception_thrown(comp_ctx, func_ctx))
goto fail; goto fail;
} }
@ -614,9 +611,9 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Load extra result from its address and push to stack */ /* Load extra result from its address and push to stack */
for (i = 0; i < ext_ret_count; i++) { for (i = 0; i < ext_ret_count; i++) {
snprintf(buf, sizeof(buf), "func%d_ext_ret%d", func_idx, i); snprintf(buf, sizeof(buf), "func%d_ext_ret%d", func_idx, i);
if (!(ext_ret = LLVMBuildLoad(comp_ctx->builder, if (!(ext_ret =
param_values[1 + param_count + i], LLVMBuildLoad(comp_ctx->builder,
buf))) { param_values[1 + param_count + i], buf))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
@ -642,12 +639,14 @@ fail:
static bool static bool
call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncType *aot_func_type, LLVMValueRef func_type_idx, AOTFuncType *aot_func_type,
LLVMValueRef table_idx, LLVMValueRef table_elem_idx, LLVMValueRef func_type_idx, LLVMValueRef table_idx,
LLVMTypeRef *param_types, LLVMValueRef *param_values, LLVMValueRef table_elem_idx,
uint32 param_count, uint32 param_cell_num, LLVMTypeRef *param_types,
uint32 result_count, uint8 *wasm_ret_types, LLVMValueRef *param_values, uint32 param_count,
LLVMValueRef *value_rets, LLVMValueRef *p_res) uint32 param_cell_num, uint32 result_count,
uint8 *wasm_ret_types, LLVMValueRef *value_rets,
LLVMValueRef *p_res)
{ {
LLVMTypeRef func_type, func_ptr_type, func_param_types[6]; LLVMTypeRef func_type, func_ptr_type, func_param_types[6];
LLVMTypeRef ret_type, ret_ptr_type, elem_ptr_type; LLVMTypeRef ret_type, ret_ptr_type, elem_ptr_type;
@ -662,7 +661,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
func_param_types[2] = I32_TYPE; /* table_elem_idx */ func_param_types[2] = I32_TYPE; /* table_elem_idx */
func_param_types[3] = I32_TYPE; /* argc */ func_param_types[3] = I32_TYPE; /* argc */
func_param_types[4] = INT32_PTR_TYPE; /* argv */ func_param_types[4] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) { if (!(func_type =
LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
aot_set_last_error("llvm add function type failed."); aot_set_last_error("llvm add function type failed.");
return false; return false;
} }
@ -687,8 +687,7 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("create LLVM function type failed."); aot_set_last_error("create LLVM function type failed.");
return false; return false;
} }
func_index = func_index = aot_get_native_symbol_index(comp_ctx, func_name);
aot_get_native_symbol_index(comp_ctx, func_name);
if (func_index < 0) { if (func_index < 0) {
return false; return false;
} }
@ -699,15 +698,16 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
else { else {
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name))
&& !(func = LLVMAddFunction(comp_ctx->module, && !(func =
func_name, func_type))) { LLVMAddFunction(comp_ctx->module, func_name, func_type))) {
aot_set_last_error("add LLVM function failed."); aot_set_last_error("add LLVM function failed.");
return false; return false;
} }
} }
ret_cell_num = wasm_get_cell_num(wasm_ret_types, result_count); ret_cell_num = wasm_get_cell_num(wasm_ret_types, result_count);
argv_cell_num = param_cell_num > ret_cell_num ? param_cell_num : ret_cell_num; argv_cell_num =
param_cell_num > ret_cell_num ? param_cell_num : ret_cell_num;
if (argv_cell_num > 64) { if (argv_cell_num > 64) {
aot_set_last_error("prepare native arguments failed: " aot_set_last_error("prepare native arguments failed: "
"maximum 64 parameter cell number supported."); "maximum 64 parameter cell number supported.");
@ -723,15 +723,16 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
snprintf(buf, sizeof(buf), "%s%d", "elem", i); snprintf(buf, sizeof(buf), "%s%d", "elem", i);
if (!(elem_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(elem_ptr = LLVMBuildInBoundsGEP(
func_ctx->argv_buf, &elem_idx, 1, buf)) comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf))
|| !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr, || !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr,
elem_ptr_type, buf))) { elem_ptr_type, buf))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
if (!(res = LLVMBuildStore(comp_ctx->builder, param_values[i], elem_ptr))) { if (!(res = LLVMBuildStore(comp_ctx->builder, param_values[i],
elem_ptr))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
return false; return false;
} }
@ -752,8 +753,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* call aot_call_indirect() function */ /* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func, if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 5,
func_param_values, 5, "res"))) { "res"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -769,8 +770,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
snprintf(buf, sizeof(buf), "argv_ret%d", i); snprintf(buf, sizeof(buf), "argv_ret%d", i);
if (!(ret_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(ret_ptr = LLVMBuildInBoundsGEP(
func_ctx->argv_buf, &ret_idx, 1, buf)) comp_ctx->builder, func_ctx->argv_buf, &ret_idx, 1, buf))
|| !(ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ret_ptr, || !(ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ret_ptr,
ret_ptr_type, buf))) { ret_ptr_type, buf))) {
aot_set_last_error("llvm build GEP or bit cast failed."); aot_set_last_error("llvm build GEP or bit cast failed.");
@ -846,9 +847,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!(table_size_const = if (!(table_size_const = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst,
LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, 1, &offset, 1, "cur_size_i8p"))) {
"cur_size_i8p"))) {
HANDLE_FAILURE("LLVMBuildGEP"); HANDLE_FAILURE("LLVMBuildGEP");
goto fail; goto fail;
} }
@ -860,24 +860,22 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!(table_size_const = LLVMBuildLoad(comp_ctx->builder, table_size_const, "cur_size"))) { if (!(table_size_const =
LLVMBuildLoad(comp_ctx->builder, table_size_const, "cur_size"))) {
HANDLE_FAILURE("LLVMBuildLoad"); HANDLE_FAILURE("LLVMBuildLoad");
goto fail; goto fail;
} }
/* Check if (uint32)elem index >= table size */ /* Check if (uint32)elem index >= table size */
if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx,
elem_idx, table_size_const, table_size_const, "cmp_elem_idx"))) {
"cmp_elem_idx"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
goto fail; goto fail;
} }
/* Throw exception if elem index >= table size */ /* Throw exception if elem index >= table size */
if (!(check_elem_idx_succ = if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) {
func_ctx->func,
"check_elem_idx_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
} }
@ -885,8 +883,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_elem_idx_succ, LLVMMoveBasicBlockAfter(check_elem_idx_succ,
LLVMGetInsertBlock(comp_ctx->builder)); LLVMGetInsertBlock(comp_ctx->builder));
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_UNDEFINED_ELEMENT, if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_UNDEFINED_ELEMENT, true,
true, cmp_elem_idx, check_elem_idx_succ))) cmp_elem_idx, check_elem_idx_succ)))
goto fail; goto fail;
/* load data as i32* */ /* load data as i32* */
@ -909,31 +907,28 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Load function index */ /* Load function index */
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
1, "table_elem"))) { "table_elem"))) {
HANDLE_FAILURE("LLVMBuildNUWAdd"); HANDLE_FAILURE("LLVMBuildNUWAdd");
goto fail; goto fail;
} }
if (!(func_idx = LLVMBuildLoad(comp_ctx->builder, if (!(func_idx =
table_elem, "func_idx"))) { LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
/* Check if func_idx == -1 */ /* Check if func_idx == -1 */
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, func_idx,
func_idx, I32_NEG_ONE, I32_NEG_ONE, "cmp_func_idx"))) {
"cmp_func_idx"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
goto fail; goto fail;
} }
/* Throw exception if func_idx == -1 */ /* Throw exception if func_idx == -1 */
if (!(check_func_idx_succ = if (!(check_func_idx_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "check_func_idx_succ"))) {
func_ctx->func,
"check_func_idx_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
} }
@ -946,33 +941,29 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
/* Load function type index */ /* Load function type index */
if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP(
func_ctx->func_type_indexes, comp_ctx->builder, func_ctx->func_type_indexes, &func_idx, 1,
&func_idx, 1,
"ftype_idx_ptr"))) { "ftype_idx_ptr"))) {
aot_set_last_error("llvm build inbounds gep failed."); aot_set_last_error("llvm build inbounds gep failed.");
goto fail; goto fail;
} }
if (!(ftype_idx = LLVMBuildLoad(comp_ctx->builder, ftype_idx_ptr, if (!(ftype_idx =
"ftype_idx"))) { LLVMBuildLoad(comp_ctx->builder, ftype_idx_ptr, "ftype_idx"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
/* Check if function type index not equal */ /* Check if function type index not equal */
if (!(cmp_ftype_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, if (!(cmp_ftype_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, ftype_idx,
ftype_idx, ftype_idx_const, ftype_idx_const, "cmp_ftype_idx"))) {
"cmp_ftype_idx"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
goto fail; goto fail;
} }
/* Throw exception if ftype_idx != ftype_idx_const */ /* Throw exception if ftype_idx != ftype_idx_const */
if (!(check_ftype_idx_succ = if (!(check_ftype_idx_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func, "check_ftype_idx_succ"))) {
func_ctx->func,
"check_ftype_idx_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
} }
@ -981,15 +972,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMGetInsertBlock(comp_ctx->builder)); LLVMGetInsertBlock(comp_ctx->builder));
if (!(aot_emit_exception(comp_ctx, func_ctx, if (!(aot_emit_exception(comp_ctx, func_ctx,
EXCE_INVALID_FUNCTION_TYPE_INDEX, EXCE_INVALID_FUNCTION_TYPE_INDEX, true,
true, cmp_ftype_idx, check_ftype_idx_succ))) cmp_ftype_idx, check_ftype_idx_succ)))
goto fail; goto fail;
/* Initialize parameter types of the LLVM function */ /* Initialize parameter types of the LLVM function */
total_param_count = 1 + func_param_count; total_param_count = 1 + func_param_count;
/* Extra function results' addresses (except the first one) are /* Extra function results' addresses (except the first one) are
* appended to aot function parameters. */ appended to aot function parameters. */
if (func_result_count > 1) if (func_result_count > 1)
total_param_count += func_result_count - 1; total_param_count += func_result_count - 1;
@ -1007,8 +998,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_types[j++] = TO_LLVM_TYPE(func_type->types[i]); param_types[j++] = TO_LLVM_TYPE(func_type->types[i]);
for (i = 1; i < func_result_count; i++, j++) { for (i = 1; i < func_result_count; i++, j++) {
param_types[j] = param_types[j] = TO_LLVM_TYPE(func_type->types[func_param_count + i]);
TO_LLVM_TYPE(func_type->types[func_param_count + i]);
if (!(param_types[j] = LLVMPointerType(param_types[j], 0))) { if (!(param_types[j] = LLVMPointerType(param_types[j], 0))) {
aot_set_last_error("llvm get pointer type failed."); aot_set_last_error("llvm get pointer type failed.");
goto fail; goto fail;
@ -1048,8 +1038,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
CHECK_LLVM_CONST(ext_ret_offset); CHECK_LLVM_CONST(ext_ret_offset);
snprintf(buf, sizeof(buf), "ext_ret%d_ptr", i - 1); snprintf(buf, sizeof(buf), "ext_ret%d_ptr", i - 1);
if (!(ext_ret_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(ext_ret_ptr =
func_ctx->argv_buf, LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->argv_buf,
&ext_ret_offset, 1, buf))) { &ext_ret_offset, 1, buf))) {
aot_set_last_error("llvm build GEP failed."); aot_set_last_error("llvm build GEP failed.");
goto fail; goto fail;
@ -1057,16 +1047,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ext_ret_ptr_type = param_types[func_param_count + i]; ext_ret_ptr_type = param_types[func_param_count + i];
snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i - 1); snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i - 1);
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ext_ret_ptr,
ext_ret_ptr, ext_ret_ptr_type, ext_ret_ptr_type, buf))) {
buf))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
goto fail; goto fail;
} }
param_values[func_param_count + i] = ext_ret_ptr; param_values[func_param_count + i] = ext_ret_ptr;
ext_cell_num += wasm_value_type_cell_num( ext_cell_num +=
func_type->types[func_param_count + i]); wasm_value_type_cell_num(func_type->types[func_param_count + i]);
} }
if (ext_cell_num > 64) { if (ext_cell_num > 64) {
@ -1091,15 +1080,12 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#endif #endif
/* Add basic blocks */ /* Add basic blocks */
block_call_import = block_call_import = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func, comp_ctx->context, func_ctx->func, "call_import");
"call_import"); block_call_non_import = LLVMAppendBasicBlockInContext(
block_call_non_import = comp_ctx->context, func_ctx->func, "call_non_import");
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func, block_return = LLVMAppendBasicBlockInContext(comp_ctx->context,
"call_non_import"); func_ctx->func, "func_return");
block_return =
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func,
"func_return");
if (!block_call_import || !block_call_non_import || !block_return) { if (!block_call_import || !block_call_non_import || !block_return) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
goto fail; goto fail;
@ -1114,17 +1100,16 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
CHECK_LLVM_CONST(import_func_count); CHECK_LLVM_CONST(import_func_count);
/* Check if func_idx < import_func_count */ /* Check if func_idx < import_func_count */
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, func_idx,
func_idx, import_func_count, import_func_count, "cmp_func_idx"))) {
"cmp_func_idx"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
goto fail; goto fail;
} }
/* If func_idx < import_func_count, jump to call import block, /* If func_idx < import_func_count, jump to call import block,
else jump to call non-import block */ else jump to call non-import block */
if (!LLVMBuildCondBr(comp_ctx->builder, cmp_func_idx, if (!LLVMBuildCondBr(comp_ctx->builder, cmp_func_idx, block_call_import,
block_call_import, block_call_non_import)) { block_call_non_import)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -1143,8 +1128,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
for (i = 0; i < func_result_count; i++) { for (i = 0; i < func_result_count; i++) {
LLVMTypeRef tmp_type = LLVMTypeRef tmp_type =
TO_LLVM_TYPE(func_type->types[func_param_count + i]); TO_LLVM_TYPE(func_type->types[func_param_count + i]);
if (!(result_phis[i] = LLVMBuildPhi(comp_ctx->builder, if (!(result_phis[i] =
tmp_type, "phi"))) { LLVMBuildPhi(comp_ctx->builder, tmp_type, "phi"))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi failed.");
goto fail; goto fail;
} }
@ -1174,13 +1159,10 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!call_aot_call_indirect_func(comp_ctx, func_ctx, if (!call_aot_call_indirect_func(
func_type, ftype_idx, comp_ctx, func_ctx, func_type, ftype_idx, tbl_idx_value, elem_idx,
tbl_idx_value, elem_idx, param_types + 1, param_values + 1, func_param_count, param_cell_num,
param_types + 1, param_values + 1, func_result_count, wasm_ret_types, value_rets, &res))
func_param_count, param_cell_num,
func_result_count, wasm_ret_types,
value_rets, &res))
goto fail; goto fail;
/* Check whether exception was thrown when executing the function */ /* Check whether exception was thrown when executing the function */
@ -1202,13 +1184,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (comp_ctx->enable_bound_check if (comp_ctx->enable_bound_check
&& !check_stack_boundary(comp_ctx, func_ctx, && !check_stack_boundary(comp_ctx, func_ctx,
param_cell_num + ext_cell_num + 1 param_cell_num + ext_cell_num
+ 1
/* Reserve some local variables */ /* Reserve some local variables */
+ 16)) + 16))
goto fail; goto fail;
/* Load function pointer */ /* Load function pointer */
if (!(func_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs, if (!(func_ptr =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs,
&func_idx, 1, "func_ptr_tmp"))) { &func_idx, 1, "func_ptr_tmp"))) {
aot_set_last_error("llvm build inbounds gep failed."); aot_set_last_error("llvm build inbounds gep failed.");
goto fail; goto fail;
@ -1219,24 +1203,22 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
if (!(llvm_func_type = LLVMFunctionType(ret_type, param_types, if (!(llvm_func_type =
total_param_count, false)) LLVMFunctionType(ret_type, param_types, total_param_count, false))
|| !(llvm_func_ptr_type = LLVMPointerType(llvm_func_type, 0))) { || !(llvm_func_ptr_type = LLVMPointerType(llvm_func_type, 0))) {
aot_set_last_error("llvm add function type failed."); aot_set_last_error("llvm add function type failed.");
goto fail; goto fail;
} }
if (!(func = LLVMBuildBitCast(comp_ctx->builder, if (!(func = LLVMBuildBitCast(comp_ctx->builder, func_ptr,
func_ptr, llvm_func_ptr_type, llvm_func_ptr_type, "indirect_func"))) {
"indirect_func"))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
goto fail; goto fail;
} }
if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func, if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func, param_values,
param_values, total_param_count, total_param_count,
func_result_count > 0 func_result_count > 0 ? "ret" : ""))) {
? "ret" : ""))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
goto fail; goto fail;
} }
@ -1254,9 +1236,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Load extra result from its address and push to stack */ /* Load extra result from its address and push to stack */
for (i = 1; i < func_result_count; i++) { for (i = 1; i < func_result_count; i++) {
snprintf(buf, sizeof(buf), "ext_ret%d", i - 1); snprintf(buf, sizeof(buf), "ext_ret%d", i - 1);
if (!(ext_ret = LLVMBuildLoad(comp_ctx->builder, if (!(ext_ret =
param_values[func_param_count + i], LLVMBuildLoad(comp_ctx->builder,
buf))) { param_values[func_param_count + i], buf))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
@ -1333,8 +1315,7 @@ fail:
} }
bool bool
aot_compile_op_ref_func(AOTCompContext *comp_ctx, aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 func_idx) uint32 func_idx)
{ {
LLVMValueRef ref_idx; LLVMValueRef ref_idx;

View File

@ -17,10 +17,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 func_idx, bool tail_call); uint32 func_idx, bool tail_call);
bool bool
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 type_idx, uint32 tbl_idx);
uint32 type_idx,
uint32 tbl_idx);
bool bool
aot_compile_op_ref_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_op_ref_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
@ -29,12 +27,10 @@ bool
aot_compile_op_ref_is_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_op_ref_is_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
bool bool
aot_compile_op_ref_func(AOTCompContext *comp_ctx, aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 func_idx); uint32 func_idx);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif
#endif /* end of _AOT_EMIT_FUNCTION_H_ */ #endif /* end of _AOT_EMIT_FUNCTION_H_ */

View File

@ -7,33 +7,33 @@
#include "aot_emit_exception.h" #include "aot_emit_exception.h"
#include "../aot/aot_runtime.h" #include "../aot/aot_runtime.h"
#define BUILD_ICMP(op, left, right, res, name) do { \ #define BUILD_ICMP(op, left, right, res, name) \
if (!(res = LLVMBuildICmp(comp_ctx->builder, op, \ do { \
left, right, name))) { \ if (!(res = \
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
aot_set_last_error("llvm build icmp failed."); \ aot_set_last_error("llvm build icmp failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define BUILD_OP(Op, left, right, res, name) do { \ #define BUILD_OP(Op, left, right, res, name) \
if (!(res = LLVMBuild##Op(comp_ctx->builder, \ do { \
left, right, name))) { \ if (!(res = LLVMBuild##Op(comp_ctx->builder, left, right, name))) { \
aot_set_last_error("llvm build " #Op " fail."); \ aot_set_last_error("llvm build " #Op " fail."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define ADD_BASIC_BLOCK(block, name) do { \ #define ADD_BASIC_BLOCK(block, name) \
do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \ func_ctx->func, name))) { \
name))) { \
aot_set_last_error("llvm add basic block failed."); \ aot_set_last_error("llvm add basic block failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define SET_BUILD_POS(block) \ #define SET_BUILD_POS(block) LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
static LLVMValueRef static LLVMValueRef
get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -64,8 +64,7 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (func_ctx->mem_space_unchanged) if (func_ctx->mem_space_unchanged)
return mem_check_bound; return mem_check_bound;
if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder, if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder, mem_check_bound,
mem_check_bound,
"mem_check_bound"))) { "mem_check_bound"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return NULL; return NULL;
@ -93,8 +92,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
comp_ctx->comp_data->memories[0].memory_flags & 0x02; comp_ctx->comp_data->memories[0].memory_flags & 0x02;
#endif #endif
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
? true : false;
CHECK_LLVM_CONST(offset_const); CHECK_LLVM_CONST(offset_const);
@ -107,8 +105,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
mem_base_addr = func_ctx->mem_info[0].mem_base_addr; mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
} }
else { else {
if (!(mem_base_addr = if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_info[0].mem_base_addr, func_ctx->mem_info[0].mem_base_addr,
"mem_base"))) { "mem_base"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
@ -116,7 +113,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
} }
aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end; aot_value =
func_ctx->block_stack.block_list_end->value_stack.value_list_end;
if (aot_value) { if (aot_value) {
/* aot_value is freed in the following POP_I32(addr), /* aot_value is freed in the following POP_I32(addr),
so save its fields here for further use */ so save its fields here for further use */
@ -136,8 +134,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
&& !LLVMIsPoison(addr) && !LLVMIsPoison(addr)
#endif #endif
) { ) {
uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(addr) uint64 mem_offset =
+ (uint64)offset; (uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset;
uint32 num_bytes_per_page = uint32 num_bytes_per_page =
comp_ctx->comp_data->memories[0].num_bytes_per_page; comp_ctx->comp_data->memories[0].num_bytes_per_page;
uint32 init_page_count = uint32 init_page_count =
@ -160,8 +158,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (is_target_64bit) { if (is_target_64bit) {
if (!(offset_const = LLVMBuildZExt(comp_ctx->builder, offset_const, if (!(offset_const = LLVMBuildZExt(comp_ctx->builder, offset_const,
I64_TYPE, "offset_i64")) I64_TYPE, "offset_i64"))
|| !(addr = LLVMBuildZExt(comp_ctx->builder, addr, || !(addr = LLVMBuildZExt(comp_ctx->builder, addr, I64_TYPE,
I64_TYPE, "addr_i64"))) { "addr_i64"))) {
aot_set_last_error("llvm build zero extend failed."); aot_set_last_error("llvm build zero extend failed.");
goto fail; goto fail;
} }
@ -186,8 +184,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ADD_BASIC_BLOCK(check_succ, "check_mem_size_succ"); ADD_BASIC_BLOCK(check_succ, "check_mem_size_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr); LLVMMoveBasicBlockAfter(check_succ, block_curr);
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
true, cmp, check_succ)) { check_succ)) {
goto fail; goto fail;
} }
@ -215,8 +213,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_succ, block_curr); LLVMMoveBasicBlockAfter(check_succ, block_curr);
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
true, cmp, check_succ)) { check_succ)) {
goto fail; goto fail;
} }
@ -240,32 +238,35 @@ fail:
return NULL; return NULL;
} }
#define BUILD_PTR_CAST(ptr_type) do { \ #define BUILD_PTR_CAST(ptr_type) \
if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr,\ do { \
ptr_type, "data_ptr"))) {\ if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr, ptr_type, \
"data_ptr"))) { \
aot_set_last_error("llvm build bit cast failed."); \ aot_set_last_error("llvm build bit cast failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define BUILD_LOAD() do { \ #define BUILD_LOAD() \
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, \ do { \
"data"))) { \ if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \
aot_set_last_error("llvm build load failed."); \ aot_set_last_error("llvm build load failed."); \
goto fail; \ goto fail; \
} \ } \
LLVMSetAlignment(value, 1); \ LLVMSetAlignment(value, 1); \
} while (0) } while (0)
#define BUILD_TRUNC(value, data_type) do { \ #define BUILD_TRUNC(value, data_type) \
if (!(value = LLVMBuildTrunc(comp_ctx->builder, value, \ do { \
data_type, "val_trunc"))){ \ if (!(value = LLVMBuildTrunc(comp_ctx->builder, value, data_type, \
"val_trunc"))) { \
aot_set_last_error("llvm build trunc failed."); \ aot_set_last_error("llvm build trunc failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define BUILD_STORE() do { \ #define BUILD_STORE() \
do { \
LLVMValueRef res; \ LLVMValueRef res; \
if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \ if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \
aot_set_last_error("llvm build store failed."); \ aot_set_last_error("llvm build store failed."); \
@ -274,17 +275,19 @@ fail:
LLVMSetAlignment(res, 1); \ LLVMSetAlignment(res, 1); \
} while (0) } while (0)
#define BUILD_SIGN_EXT(dst_type) do { \ #define BUILD_SIGN_EXT(dst_type) \
if (!(value = LLVMBuildSExt(comp_ctx->builder, value, \ do { \
dst_type, "data_s_ext"))) { \ if (!(value = LLVMBuildSExt(comp_ctx->builder, value, dst_type, \
"data_s_ext"))) { \
aot_set_last_error("llvm build sign ext failed."); \ aot_set_last_error("llvm build sign ext failed."); \
goto fail; \ goto fail; \
} \ } \
} while (0) } while (0)
#define BUILD_ZERO_EXT(dst_type) do { \ #define BUILD_ZERO_EXT(dst_type) \
if (!(value = LLVMBuildZExt(comp_ctx->builder, value, \ do { \
dst_type, "data_z_ext"))) { \ if (!(value = LLVMBuildZExt(comp_ctx->builder, value, dst_type, \
"data_z_ext"))) { \
aot_set_last_error("llvm build zero ext failed."); \ aot_set_last_error("llvm build zero ext failed."); \
goto fail; \ goto fail; \
} \ } \
@ -303,8 +306,8 @@ check_memory_alignment(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
CHECK_LLVM_CONST(align_mask); CHECK_LLVM_CONST(align_mask);
/* Convert pointer to int */ /* Convert pointer to int */
if (!(addr = LLVMBuildPtrToInt(comp_ctx->builder, addr, if (!(addr = LLVMBuildPtrToInt(comp_ctx->builder, addr, I32_TYPE,
I32_TYPE, "address"))) { "address"))) {
aot_set_last_error("llvm build ptr to int failed."); aot_set_last_error("llvm build ptr to int failed.");
goto fail; goto fail;
} }
@ -317,9 +320,8 @@ check_memory_alignment(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ADD_BASIC_BLOCK(check_align_succ, "check_align_succ"); ADD_BASIC_BLOCK(check_align_succ, "check_align_succ");
LLVMMoveBasicBlockAfter(check_align_succ, block_curr); LLVMMoveBasicBlockAfter(check_align_succ, block_curr);
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNALIGNED_ATOMIC, true,
EXCE_UNALIGNED_ATOMIC, res, check_align_succ)) {
true, res, check_align_succ)) {
goto fail; goto fail;
} }
@ -330,12 +332,12 @@ fail:
return false; return false;
} }
#define BUILD_ATOMIC_LOAD(align) do { \ #define BUILD_ATOMIC_LOAD(align) \
do { \
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \ if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
goto fail; \ goto fail; \
} \ } \
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, \ if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \
"data"))) { \
aot_set_last_error("llvm build load failed."); \ aot_set_last_error("llvm build load failed."); \
goto fail; \ goto fail; \
} \ } \
@ -344,7 +346,8 @@ fail:
LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \ LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \
} while (0) } while (0)
#define BUILD_ATOMIC_STORE(align) do { \ #define BUILD_ATOMIC_STORE(align) \
do { \
LLVMValueRef res; \ LLVMValueRef res; \
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \ if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
goto fail; \ goto fail; \
@ -361,8 +364,8 @@ fail:
bool bool
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, uint32 align, uint32 offset, uint32 bytes, bool sign,
bool sign, bool atomic) bool atomic)
{ {
LLVMValueRef maddr, value = NULL; LLVMValueRef maddr, value = NULL;
@ -413,8 +416,8 @@ fail:
bool bool
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, uint32 align, uint32 offset, uint32 bytes, bool sign,
bool sign, bool atomic) bool atomic)
{ {
LLVMValueRef maddr, value = NULL; LLVMValueRef maddr, value = NULL;
@ -627,10 +630,9 @@ get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
mem_size = func_ctx->mem_info[0].mem_cur_page_count_addr; mem_size = func_ctx->mem_info[0].mem_cur_page_count_addr;
} }
else { else {
if (!(mem_size = if (!(mem_size = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder,
func_ctx->mem_info[0].mem_cur_page_count_addr, func_ctx->mem_info[0].mem_cur_page_count_addr, "mem_size"))) {
"mem_size"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
goto fail; goto fail;
} }
@ -707,8 +709,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
char *func_name = "aot_enlarge_memory"; char *func_name = "aot_enlarge_memory";
/* AOT mode, delcare the function */ /* AOT mode, delcare the function */
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name))
&& !(func = LLVMAddFunction(comp_ctx->module, && !(func =
func_name, func_type))) { LLVMAddFunction(comp_ctx->module, func_name, func_type))) {
aot_set_last_error("llvm add function failed."); aot_set_last_error("llvm add function failed.");
return false; return false;
} }
@ -717,8 +719,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
/* Call function aot_enlarge_memory() */ /* Call function aot_enlarge_memory() */
param_values[0] = func_ctx->aot_inst; param_values[0] = func_ctx->aot_inst;
param_values[1] = delta; param_values[1] = delta;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
param_values, 2, "call"))) { "call"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -726,9 +728,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
BUILD_ICMP(LLVMIntUGT, ret_value, I8_ZERO, ret_value, "mem_grow_ret"); BUILD_ICMP(LLVMIntUGT, ret_value, I8_ZERO, ret_value, "mem_grow_ret");
/* ret_value = ret_value == true ? delta : pre_page_count */ /* ret_value = ret_value == true ? delta : pre_page_count */
if (!(ret_value = LLVMBuildSelect(comp_ctx->builder, ret_value, if (!(ret_value = LLVMBuildSelect(comp_ctx->builder, ret_value, mem_size,
mem_size, I32_NEG_ONE, I32_NEG_ONE, "mem_grow_ret"))) {
"mem_grow_ret"))) {
aot_set_last_error("llvm build select failed."); aot_set_last_error("llvm build select failed.");
return false; return false;
} }
@ -763,8 +764,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
mem_base_addr = func_ctx->mem_info[0].mem_base_addr; mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
} }
else { else {
if (!(mem_base_addr = if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_info[0].mem_base_addr, func_ctx->mem_info[0].mem_base_addr,
"mem_base"))) { "mem_base"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
@ -789,12 +789,10 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 init_page_count = uint32 init_page_count =
comp_ctx->comp_data->memories[0].mem_init_page_count; comp_ctx->comp_data->memories[0].mem_init_page_count;
uint32 mem_data_size = num_bytes_per_page * init_page_count; uint32 mem_data_size = num_bytes_per_page * init_page_count;
if (mem_data_size > 0 if (mem_data_size > 0 && mem_offset + mem_len <= mem_data_size) {
&& mem_offset + mem_len <= mem_data_size) {
/* inside memory space */ /* inside memory space */
/* maddr = mem_base_addr + moffset */ /* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
mem_base_addr,
&offset, 1, "maddr"))) { &offset, 1, "maddr"))) {
aot_set_last_error("llvm build add failed."); aot_set_last_error("llvm build add failed.");
goto fail; goto fail;
@ -807,8 +805,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
mem_size = func_ctx->mem_info[0].mem_data_size_addr; mem_size = func_ctx->mem_info[0].mem_data_size_addr;
} }
else { else {
if (!(mem_size = if (!(mem_size = LLVMBuildLoad(comp_ctx->builder,
LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_info[0].mem_data_size_addr, func_ctx->mem_info[0].mem_data_size_addr,
"mem_size"))) { "mem_size"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
@ -819,16 +816,17 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ADD_BASIC_BLOCK(check_succ, "check_succ"); ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr); LLVMMoveBasicBlockAfter(check_succ, block_curr);
offset = LLVMBuildZExt(comp_ctx->builder, offset, I64_TYPE, "extend_offset"); offset =
LLVMBuildZExt(comp_ctx->builder, offset, I64_TYPE, "extend_offset");
bytes = LLVMBuildZExt(comp_ctx->builder, bytes, I64_TYPE, "extend_len"); bytes = LLVMBuildZExt(comp_ctx->builder, bytes, I64_TYPE, "extend_len");
mem_size = LLVMBuildZExt(comp_ctx->builder, mem_size, I64_TYPE, "extend_size"); mem_size =
LLVMBuildZExt(comp_ctx->builder, mem_size, I64_TYPE, "extend_size");
BUILD_OP(Add, offset, bytes, max_addr, "max_addr"); BUILD_OP(Add, offset, bytes, max_addr, "max_addr");
BUILD_ICMP(LLVMIntUGT, max_addr, mem_size, cmp, BUILD_ICMP(LLVMIntUGT, max_addr, mem_size, cmp, "cmp_max_mem_addr");
"cmp_max_mem_addr");
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
true, cmp, check_succ)) { check_succ)) {
goto fail; goto fail;
} }
@ -874,8 +872,8 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_values[2] = offset; param_values[2] = offset;
param_values[3] = len; param_values[3] = len;
param_values[4] = dst; param_values[4] = dst;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5,
param_values, 5, "call"))) { "call"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -888,8 +886,8 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(mem_init_fail, block_curr); LLVMMoveBasicBlockAfter(mem_init_fail, block_curr);
LLVMMoveBasicBlockAfter(init_success, block_curr); LLVMMoveBasicBlockAfter(init_success, block_curr);
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, init_success,
init_success, mem_init_fail)) { mem_init_fail)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -927,8 +925,8 @@ aot_compile_op_data_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Call function aot_data_drop() */ /* Call function aot_data_drop() */
param_values[0] = func_ctx->aot_inst; param_values[0] = func_ctx->aot_inst;
param_values[1] = seg; param_values[1] = seg;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
param_values, 2, "call"))) { "call"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -947,18 +945,16 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
POP_I32(src); POP_I32(src);
POP_I32(dst); POP_I32(dst);
if (!(src_addr = if (!(src_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, src, len)))
check_bulk_memory_overflow(comp_ctx, func_ctx, src, len)))
return false; return false;
if (!(dst_addr = if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
return false; return false;
/* TODO: lookup func ptr of "memmove" to call for XIP mode */ /* TODO: lookup func ptr of "memmove" to call for XIP mode */
if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1, if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1, src_addr, 1,
src_addr, 1, len))) { len))) {
aot_set_last_error("llvm build memmove failed."); aot_set_last_error("llvm build memmove failed.");
return false; return false;
} }
@ -976,20 +972,18 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
POP_I32(val); POP_I32(val);
POP_I32(dst); POP_I32(dst);
if (!(dst_addr = if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
return false; return false;
if (!(val = LLVMBuildIntCast2(comp_ctx->builder, val, INT8_TYPE, if (!(val = LLVMBuildIntCast2(comp_ctx->builder, val, INT8_TYPE, true,
true, "mem_set_value"))) { "mem_set_value"))) {
aot_set_last_error("llvm build int cast2 failed."); aot_set_last_error("llvm build int cast2 failed.");
return false; return false;
} }
/* TODO: lookup func ptr of "memset" to call for XIP mode */ /* TODO: lookup func ptr of "memset" to call for XIP mode */
if (!(res = LLVMBuildMemSet(comp_ctx->builder, dst_addr, if (!(res = LLVMBuildMemSet(comp_ctx->builder, dst_addr, val, len, 1))) {
val, len, 1))) {
aot_set_last_error("llvm build memset failed."); aot_set_last_error("llvm build memset failed.");
return false; return false;
} }
@ -1001,11 +995,9 @@ fail:
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
bool bool
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 atomic_op, uint8 op_type, uint32 align,
uint8 atomic_op, uint8 op_type, uint32 offset, uint32 bytes)
uint32 align, uint32 offset,
uint32 bytes)
{ {
LLVMValueRef maddr, value, result; LLVMValueRef maddr, value, result;
@ -1042,9 +1034,8 @@ aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx,
break; break;
} }
if (!(result = if (!(result = LLVMBuildAtomicRMW(
LLVMBuildAtomicRMW(comp_ctx->builder, comp_ctx->builder, atomic_op, maddr, value,
atomic_op, maddr, value,
LLVMAtomicOrderingSequentiallyConsistent, false))) { LLVMAtomicOrderingSequentiallyConsistent, false))) {
goto fail; goto fail;
} }
@ -1052,15 +1043,15 @@ aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx,
LLVMSetVolatile(result, true); LLVMSetVolatile(result, true);
if (op_type == VALUE_TYPE_I32) { if (op_type == VALUE_TYPE_I32) {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
I32_TYPE, "result_i32"))) { "result_i32"))) {
goto fail; goto fail;
} }
PUSH_I32(result); PUSH_I32(result);
} }
else { else {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
I64_TYPE, "result_i64"))) { "result_i64"))) {
goto fail; goto fail;
} }
PUSH_I64(result); PUSH_I64(result);
@ -1073,9 +1064,8 @@ fail:
bool bool
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx, aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 op_type,
uint8 op_type, uint32 align, uint32 align, uint32 offset, uint32 bytes)
uint32 offset, uint32 bytes)
{ {
LLVMValueRef maddr, value, expect, result; LLVMValueRef maddr, value, expect, result;
@ -1120,11 +1110,10 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
break; break;
} }
if (!(result = if (!(result = LLVMBuildAtomicCmpXchg(
LLVMBuildAtomicCmpXchg(comp_ctx->builder, maddr, expect, value, comp_ctx->builder, maddr, expect, value,
LLVMAtomicOrderingSequentiallyConsistent, LLVMAtomicOrderingSequentiallyConsistent,
LLVMAtomicOrderingSequentiallyConsistent, LLVMAtomicOrderingSequentiallyConsistent, false))) {
false))) {
goto fail; goto fail;
} }
@ -1132,22 +1121,21 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
/* CmpXchg return {i32, i1} structure, /* CmpXchg return {i32, i1} structure,
we need to extrack the previous_value from the structure */ we need to extrack the previous_value from the structure */
if (!(result = if (!(result = LLVMBuildExtractValue(comp_ctx->builder, result, 0,
LLVMBuildExtractValue(comp_ctx->builder, "previous_value"))) {
result, 0, "previous_value"))) {
goto fail; goto fail;
} }
if (op_type == VALUE_TYPE_I32) { if (op_type == VALUE_TYPE_I32) {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
I32_TYPE, "result_i32"))) { "result_i32"))) {
goto fail; goto fail;
} }
PUSH_I32(result); PUSH_I32(result);
} }
else { else {
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
I64_TYPE, "result_i64"))) { "result_i64"))) {
goto fail; goto fail;
} }
PUSH_I64(result); PUSH_I64(result);
@ -1160,8 +1148,8 @@ fail:
bool bool
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 op_type, uint32 align, uint8 op_type, uint32 align, uint32 offset,
uint32 offset, uint32 bytes) uint32 bytes)
{ {
LLVMValueRef maddr, value, timeout, expect, cmp; LLVMValueRef maddr, value, timeout, expect, cmp;
LLVMValueRef param_values[5], ret_value, func, is_wait64; LLVMValueRef param_values[5], ret_value, func, is_wait64;
@ -1174,9 +1162,8 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (op_type == VALUE_TYPE_I32) { if (op_type == VALUE_TYPE_I32) {
POP_I32(expect); POP_I32(expect);
is_wait64 = I8_CONST(false); is_wait64 = I8_CONST(false);
if (!(expect = if (!(expect = LLVMBuildZExt(comp_ctx->builder, expect, I64_TYPE,
LLVMBuildZExt(comp_ctx->builder, expect, "expect_i64"))) {
I64_TYPE, "expect_i64"))) {
goto fail; goto fail;
} }
} }
@ -1208,8 +1195,8 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_values[2] = expect; param_values[2] = expect;
param_values[3] = timeout; param_values[3] = timeout;
param_values[4] = is_wait64; param_values[4] = is_wait64;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5,
param_values, 5, "call"))) { "call"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }
@ -1222,8 +1209,7 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(wait_fail, block_curr); LLVMMoveBasicBlockAfter(wait_fail, block_curr);
LLVMMoveBasicBlockAfter(wait_success, block_curr); LLVMMoveBasicBlockAfter(wait_success, block_curr);
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, if (!LLVMBuildCondBr(comp_ctx->builder, cmp, wait_success, wait_fail)) {
wait_success, wait_fail)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
goto fail; goto fail;
} }
@ -1246,8 +1232,8 @@ fail:
bool bool
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx, aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint32 align,
uint32 align, uint32 offset, uint32 bytes) uint32 offset, uint32 bytes)
{ {
LLVMValueRef maddr, value, count; LLVMValueRef maddr, value, count;
LLVMValueRef param_values[3], ret_value, func; LLVMValueRef param_values[3], ret_value, func;
@ -1272,8 +1258,8 @@ aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
param_values[0] = func_ctx->aot_inst; param_values[0] = func_ctx->aot_inst;
param_values[1] = maddr; param_values[1] = maddr;
param_values[2] = count; param_values[2] = count;
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 3,
param_values, 3, "call"))) { "call"))) {
aot_set_last_error("llvm build call failed."); aot_set_last_error("llvm build call failed.");
return false; return false;
} }

View File

@ -17,13 +17,13 @@ extern "C" {
bool bool
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, uint32 align, uint32 offset, uint32 bytes, bool sign,
bool sign, bool atomic); bool atomic);
bool bool
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, uint32 align, uint32 offset, uint32 bytes, bool sign,
bool sign, bool atomic); bool atomic);
bool bool
aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -35,11 +35,13 @@ aot_compile_op_f64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool bool
aot_compile_op_i32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, bool atomic); uint32 align, uint32 offset, uint32 bytes,
bool atomic);
bool bool
aot_compile_op_i64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 align, uint32 offset, uint32 bytes, bool atomic); uint32 align, uint32 offset, uint32 bytes,
bool atomic);
bool bool
aot_compile_op_f32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -77,27 +79,24 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
bool bool
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 atomic_op, uint8 op_type, uint32 align,
uint8 atomic_op, uint8 op_type, uint32 offset, uint32 bytes);
uint32 align, uint32 offset,
uint32 bytes);
bool bool
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx, aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 op_type,
uint8 op_type, uint32 align, uint32 align, uint32 offset, uint32 bytes);
uint32 offset, uint32 bytes);
bool bool
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 op_type, uint32 align, uint8 op_type, uint32 align, uint32 offset,
uint32 offset, uint32 bytes); uint32 bytes);
bool bool
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx, aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint32 align,
uint32 align, uint32 offset, uint32 bytes); uint32 offset, uint32 bytes);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -105,4 +104,3 @@ aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
#endif #endif
#endif /* end of _AOT_EMIT_MEMORY_H_ */ #endif /* end of _AOT_EMIT_MEMORY_H_ */

View File

@ -11,24 +11,27 @@
#include <stdarg.h> #include <stdarg.h>
#define LLVM_BUILD_ICMP(op, left, right, res, name) do { \ #define LLVM_BUILD_ICMP(op, left, right, res, name) \
if (!(res = LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \ do { \
if (!(res = \
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
aot_set_last_error("llvm build " name " fail."); \ aot_set_last_error("llvm build " name " fail."); \
return false; \ return false; \
} \ } \
} while (0) } while (0)
#define LLVM_BUILD_OP(Op, left, right, res, name, err_ret) do { \ #define LLVM_BUILD_OP(Op, left, right, res, name, err_ret) \
do { \
if (!(res = LLVMBuild##Op(comp_ctx->builder, left, right, name))) { \ if (!(res = LLVMBuild##Op(comp_ctx->builder, left, right, name))) { \
aot_set_last_error("llvm build " #name " fail."); \ aot_set_last_error("llvm build " #name " fail."); \
return err_ret; \ return err_ret; \
} \ } \
} while (0) } while (0)
#define ADD_BASIC_BLOCK(block, name) do { \ #define ADD_BASIC_BLOCK(block, name) \
do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \ func_ctx->func, name))) { \
name))) { \
aot_set_last_error("llvm add basic block failed."); \ aot_set_last_error("llvm add basic block failed."); \
goto fail; \ goto fail; \
} \ } \
@ -48,45 +51,51 @@
|| (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0))) || (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0)))
#endif #endif
#define CHECK_INT_OVERFLOW(type) do { \ #define CHECK_INT_OVERFLOW(type) \
do { \
LLVMValueRef cmp_min_int, cmp_neg_one; \ LLVMValueRef cmp_min_int, cmp_neg_one; \
LLVM_BUILD_ICMP(LLVMIntEQ, left, type##_MIN, \ LLVM_BUILD_ICMP(LLVMIntEQ, left, type##_MIN, cmp_min_int, \
cmp_min_int, "cmp_min_int"); \ "cmp_min_int"); \
LLVM_BUILD_ICMP(LLVMIntEQ, right, type##_NEG_ONE, \ LLVM_BUILD_ICMP(LLVMIntEQ, right, type##_NEG_ONE, cmp_neg_one, \
cmp_neg_one, "cmp_neg_one"); \ "cmp_neg_one"); \
LLVM_BUILD_OP(And, cmp_min_int, cmp_neg_one, \ LLVM_BUILD_OP(And, cmp_min_int, cmp_neg_one, overflow, "overflow", \
overflow, "overflow", false); \ false); \
} while (0) } while (0)
#define PUSH_INT(v) do { \ #define PUSH_INT(v) \
do { \
if (is_i32) \ if (is_i32) \
PUSH_I32(v); \ PUSH_I32(v); \
else \ else \
PUSH_I64(v); \ PUSH_I64(v); \
} while (0) } while (0)
#define POP_INT(v) do { \ #define POP_INT(v) \
do { \
if (is_i32) \ if (is_i32) \
POP_I32(v); \ POP_I32(v); \
else \ else \
POP_I64(v); \ POP_I64(v); \
} while (0) } while (0)
#define PUSH_FLOAT(v) do { \ #define PUSH_FLOAT(v) \
do { \
if (is_f32) \ if (is_f32) \
PUSH_F32(v); \ PUSH_F32(v); \
else \ else \
PUSH_F64(v); \ PUSH_F64(v); \
} while (0) } while (0)
#define POP_FLOAT(v) do { \ #define POP_FLOAT(v) \
do { \
if (is_f32) \ if (is_f32) \
POP_F32(v); \ POP_F32(v); \
else \ else \
POP_F64(v); \ POP_F64(v); \
} while (0) } while (0)
#define DEF_INT_UNARY_OP(op, err) do { \ #define DEF_INT_UNARY_OP(op, err) \
do { \
LLVMValueRef res, operand; \ LLVMValueRef res, operand; \
POP_INT(operand); \ POP_INT(operand); \
if (!(res = op)) { \ if (!(res = op)) { \
@ -97,7 +106,8 @@
PUSH_INT(res); \ PUSH_INT(res); \
} while (0) } while (0)
#define DEF_INT_BINARY_OP(op, err) do { \ #define DEF_INT_BINARY_OP(op, err) \
do { \
LLVMValueRef res, left, right; \ LLVMValueRef res, left, right; \
POP_INT(right); \ POP_INT(right); \
POP_INT(left); \ POP_INT(left); \
@ -109,7 +119,8 @@
PUSH_INT(res); \ PUSH_INT(res); \
} while (0) } while (0)
#define DEF_FP_UNARY_OP(op, err) do { \ #define DEF_FP_UNARY_OP(op, err) \
do { \
LLVMValueRef res, operand; \ LLVMValueRef res, operand; \
POP_FLOAT(operand); \ POP_FLOAT(operand); \
if (!(res = op)) { \ if (!(res = op)) { \
@ -120,7 +131,8 @@
PUSH_FLOAT(res); \ PUSH_FLOAT(res); \
} while (0) } while (0)
#define DEF_FP_BINARY_OP(op, err) do { \ #define DEF_FP_BINARY_OP(op, err) \
do { \
LLVMValueRef res, left, right; \ LLVMValueRef res, left, right; \
POP_FLOAT(right); \ POP_FLOAT(right); \
POP_FLOAT(left); \ POP_FLOAT(left); \
@ -132,24 +144,25 @@
PUSH_FLOAT(res); \ PUSH_FLOAT(res); \
} while (0) } while (0)
#define SHIFT_COUNT_MASK do { \ #define SHIFT_COUNT_MASK \
/* LLVM has undefined behavior if shift count is greater than bits count \ do { \
* while Webassembly spec requires the shift count be wrapped. */ \ /* LLVM has undefined behavior if shift count is greater than \
* bits count while Webassembly spec requires the shift count \
* be wrapped. \
*/ \
LLVMValueRef shift_count_mask, bits_minus_one; \ LLVMValueRef shift_count_mask, bits_minus_one; \
bits_minus_one = is_i32 ? I32_31 : I64_63; \ bits_minus_one = is_i32 ? I32_31 : I64_63; \
LLVM_BUILD_OP(And, right, bits_minus_one, \ LLVM_BUILD_OP(And, right, bits_minus_one, shift_count_mask, \
shift_count_mask, "shift_count_mask", NULL); \ "shift_count_mask", NULL); \
right = shift_count_mask; \ right = shift_count_mask; \
} while (0) } while (0)
/* Call llvm constrained floating-point intrinsic */ /* Call llvm constrained floating-point intrinsic */
static LLVMValueRef static LLVMValueRef
call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx, call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
bool is_f32, bool is_f32,
const char *intrinsic, const char *intrinsic, ...)
...)
{ {
va_list param_value_list; va_list param_value_list;
LLVMValueRef ret; LLVMValueRef ret;
@ -164,8 +177,7 @@ call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
va_start(param_value_list, intrinsic); va_start(param_value_list, intrinsic);
ret = ret = aot_call_llvm_intrinsic_v(comp_ctx, func_ctx, intrinsic, ret_type,
aot_call_llvm_intrinsic_v(comp_ctx, func_ctx, intrinsic, ret_type,
param_types, param_count, param_value_list); param_types, param_count, param_value_list);
va_end(param_value_list); va_end(param_value_list);
@ -178,8 +190,7 @@ static LLVMValueRef
call_llvm_libm_experimental_constrained_intrinsic(AOTCompContext *comp_ctx, call_llvm_libm_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
bool is_f32, bool is_f32,
const char *intrinsic, const char *intrinsic, ...)
...)
{ {
va_list param_value_list; va_list param_value_list;
LLVMValueRef ret; LLVMValueRef ret;
@ -190,8 +201,8 @@ call_llvm_libm_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
va_start(param_value_list, intrinsic); va_start(param_value_list, intrinsic);
ret = aot_call_llvm_intrinsic_v(comp_ctx, func_ctx, intrinsic, ret_type, param_types, ret = aot_call_llvm_intrinsic_v(comp_ctx, func_ctx, intrinsic, ret_type,
3, param_value_list); param_types, 3, param_value_list);
va_end(param_value_list); va_end(param_value_list);
@ -199,39 +210,35 @@ call_llvm_libm_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_op_float_min_max(AOTCompContext *comp_ctx, compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, bool is_f32, LLVMValueRef left, LLVMValueRef right,
bool is_f32,
LLVMValueRef left,
LLVMValueRef right,
bool is_min) bool is_min)
{ {
LLVMTypeRef param_types[2], ret_type = is_f32 ? F32_TYPE : F64_TYPE, LLVMTypeRef param_types[2], ret_type = is_f32 ? F32_TYPE : F64_TYPE,
int_type = is_f32 ? I32_TYPE : I64_TYPE; int_type = is_f32 ? I32_TYPE : I64_TYPE;
LLVMValueRef cmp, is_eq, is_nan, ret, left_int, right_int, tmp, LLVMValueRef cmp, is_eq, is_nan, ret, left_int, right_int, tmp,
nan = LLVMConstRealOfString(ret_type, "NaN"); nan = LLVMConstRealOfString(ret_type, "NaN");
char *intrinsic = is_min ? char *intrinsic = is_min ? (is_f32 ? "llvm.minnum.f32" : "llvm.minnum.f64")
(is_f32 ? "llvm.minnum.f32" : "llvm.minnum.f64") : : (is_f32 ? "llvm.maxnum.f32" : "llvm.maxnum.f64");
(is_f32 ? "llvm.maxnum.f32" : "llvm.maxnum.f64");
CHECK_LLVM_CONST(nan); CHECK_LLVM_CONST(nan);
param_types[0] = param_types[1] = ret_type; param_types[0] = param_types[1] = ret_type;
if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, left, right,
left, right, "is_nan")) "is_nan"))
|| !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, || !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, left, right,
left, right, "is_eq"))) { "is_eq"))) {
aot_set_last_error("llvm build fcmp fail."); aot_set_last_error("llvm build fcmp fail.");
return NULL; return NULL;
} }
/* If left and right are equal, they may be zero with different sign. /* If left and right are equal, they may be zero with different sign.
* Webassembly spec assert -0 < +0. So do a bitwise here. */ Webassembly spec assert -0 < +0. So do a bitwise here. */
if (!(left_int = LLVMBuildBitCast(comp_ctx->builder, left, if (!(left_int =
int_type, "left_int")) LLVMBuildBitCast(comp_ctx->builder, left, int_type, "left_int"))
|| !(right_int = LLVMBuildBitCast(comp_ctx->builder, right, || !(right_int = LLVMBuildBitCast(comp_ctx->builder, right, int_type,
int_type, "right_int"))) { "right_int"))) {
aot_set_last_error("llvm build bitcast fail."); aot_set_last_error("llvm build bitcast fail.");
return NULL; return NULL;
} }
@ -246,24 +253,16 @@ compile_op_float_min_max(AOTCompContext *comp_ctx,
return NULL; return NULL;
} }
if (!(cmp = if (!(cmp = aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, ret_type,
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, ret_type,
param_types, 2, left, right))) param_types, 2, left, right)))
return NULL; return NULL;
if (!(cmp = LLVMBuildSelect(comp_ctx->builder, if (!(cmp = LLVMBuildSelect(comp_ctx->builder, is_eq, tmp, cmp, "cmp"))) {
is_eq,
tmp,
cmp,
"cmp"))) {
aot_set_last_error("llvm build select fail."); aot_set_last_error("llvm build select fail.");
return NULL; return NULL;
} }
if (!(ret = LLVMBuildSelect(comp_ctx->builder, if (!(ret = LLVMBuildSelect(comp_ctx->builder, is_nan, nan, cmp,
is_nan,
nan,
cmp,
is_min ? "min" : "max"))) { is_min ? "min" : "max"))) {
aot_set_last_error("llvm build select fail."); aot_set_last_error("llvm build select fail.");
return NULL; return NULL;
@ -283,6 +282,7 @@ typedef enum BitCountType {
POP_CNT64 POP_CNT64
} BitCountType; } BitCountType;
/* clang-format off */
static char *bit_cnt_llvm_intrinsic[] = { static char *bit_cnt_llvm_intrinsic[] = {
"llvm.ctlz.i32", "llvm.ctlz.i32",
"llvm.ctlz.i64", "llvm.ctlz.i64",
@ -291,6 +291,7 @@ static char *bit_cnt_llvm_intrinsic[] = {
"llvm.ctpop.i32", "llvm.ctpop.i32",
"llvm.ctpop.i64", "llvm.ctpop.i64",
}; };
/* clang-format on */
static bool static bool
aot_compile_int_bit_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_int_bit_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -307,23 +308,14 @@ aot_compile_int_bit_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Call the LLVM intrinsic function */ /* Call the LLVM intrinsic function */
if (type < POP_CNT32) if (type < POP_CNT32)
DEF_INT_UNARY_OP(aot_call_llvm_intrinsic(comp_ctx, DEF_INT_UNARY_OP(aot_call_llvm_intrinsic(
func_ctx, comp_ctx, func_ctx, bit_cnt_llvm_intrinsic[type],
bit_cnt_llvm_intrinsic[type], ret_type, param_types, 2, operand, zero_undef),
ret_type,
param_types,
2,
operand,
zero_undef),
NULL); NULL);
else else
DEF_INT_UNARY_OP(aot_call_llvm_intrinsic(comp_ctx, DEF_INT_UNARY_OP(aot_call_llvm_intrinsic(
func_ctx, comp_ctx, func_ctx, bit_cnt_llvm_intrinsic[type],
bit_cnt_llvm_intrinsic[type], ret_type, param_types, 1, operand),
ret_type,
param_types,
1,
operand),
NULL); NULL);
return true; return true;
@ -334,8 +326,8 @@ fail:
static bool static bool
compile_rems(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, compile_rems(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef left, LLVMValueRef right, LLVMValueRef left, LLVMValueRef right, LLVMValueRef overflow_cond,
LLVMValueRef overflow_cond, bool is_i32) bool is_i32)
{ {
LLVMValueRef phi, no_overflow_value, zero = is_i32 ? I32_ZERO : I64_ZERO; LLVMValueRef phi, no_overflow_value, zero = is_i32 ? I32_ZERO : I64_ZERO;
LLVMBasicBlockRef block_curr, no_overflow_block, rems_end_block; LLVMBasicBlockRef block_curr, no_overflow_block, rems_end_block;
@ -347,8 +339,8 @@ compile_rems(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
ADD_BASIC_BLOCK(no_overflow_block, "rems_no_overflow"); ADD_BASIC_BLOCK(no_overflow_block, "rems_no_overflow");
/* Create condition br */ /* Create condition br */
if (!LLVMBuildCondBr(comp_ctx->builder, overflow_cond, if (!LLVMBuildCondBr(comp_ctx->builder, overflow_cond, rems_end_block,
rems_end_block, no_overflow_block)) { no_overflow_block)) {
aot_set_last_error("llvm build cond br failed."); aot_set_last_error("llvm build cond br failed.");
return false; return false;
} }
@ -369,8 +361,7 @@ compile_rems(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMPositionBuilderAtEnd(comp_ctx->builder, rems_end_block); LLVMPositionBuilderAtEnd(comp_ctx->builder, rems_end_block);
/* Create result phi */ /* Create result phi */
if (!(phi = LLVMBuildPhi(comp_ctx->builder, if (!(phi = LLVMBuildPhi(comp_ctx->builder, is_i32 ? I32_TYPE : I64_TYPE,
is_i32 ? I32_TYPE : I64_TYPE,
"rems_result_phi"))) { "rems_result_phi"))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi failed.");
return false; return false;
@ -398,10 +389,8 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef left, right, cmp_div_zero, overflow, res; LLVMValueRef left, right, cmp_div_zero, overflow, res;
LLVMBasicBlockRef check_div_zero_succ, check_overflow_succ; LLVMBasicBlockRef check_div_zero_succ, check_overflow_succ;
bh_assert(arith_op == INT_DIV_S bh_assert(arith_op == INT_DIV_S || arith_op == INT_DIV_U
|| arith_op == INT_DIV_U || arith_op == INT_REM_S || arith_op == INT_REM_U);
|| arith_op == INT_REM_S
|| arith_op == INT_REM_U);
POP_INT(right); POP_INT(right);
POP_INT(left); POP_INT(left);
@ -424,11 +413,12 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
case 0: case 0:
/* Directly throw exception if divided by zero */ /* Directly throw exception if divided by zero */
if (!(aot_emit_exception(comp_ctx, func_ctx, if (!(aot_emit_exception(comp_ctx, func_ctx,
EXCE_INTEGER_DIVIDE_BY_ZERO, EXCE_INTEGER_DIVIDE_BY_ZERO, false,
false, NULL, NULL))) NULL, NULL)))
goto fail; goto fail;
return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); return aot_handle_next_reachable_block(comp_ctx, func_ctx,
p_frame_ip);
case 1: case 1:
if (arith_op == INT_DIV_S || arith_op == INT_DIV_U) if (arith_op == INT_DIV_S || arith_op == INT_DIV_U)
PUSH_INT(left); PUSH_INT(left);
@ -437,17 +427,15 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return true; return true;
case -1: case -1:
if (arith_op == INT_DIV_S) { if (arith_op == INT_DIV_S) {
LLVM_BUILD_ICMP(LLVMIntEQ, left, LLVM_BUILD_ICMP(LLVMIntEQ, left, is_i32 ? I32_MIN : I64_MIN,
is_i32 ? I32_MIN : I64_MIN,
overflow, "overflow"); overflow, "overflow");
ADD_BASIC_BLOCK(check_overflow_succ, ADD_BASIC_BLOCK(check_overflow_succ,
"check_overflow_success"); "check_overflow_success");
/* Throw conditional exception if overflow */ /* Throw conditional exception if overflow */
if (!(aot_emit_exception(comp_ctx, func_ctx, if (!(aot_emit_exception(comp_ctx, func_ctx,
EXCE_INTEGER_OVERFLOW, EXCE_INTEGER_OVERFLOW, true,
true, overflow, overflow, check_overflow_succ)))
check_overflow_succ)))
goto fail; goto fail;
/* Push -(left) to stack */ /* Push -(left) to stack */
@ -515,8 +503,8 @@ handle_default:
/* Throw conditional exception if integer overflow */ /* Throw conditional exception if integer overflow */
if (!(aot_emit_exception(comp_ctx, func_ctx, if (!(aot_emit_exception(comp_ctx, func_ctx,
EXCE_INTEGER_OVERFLOW, EXCE_INTEGER_OVERFLOW, true, overflow,
true, overflow, check_overflow_succ))) check_overflow_succ)))
goto fail; goto fail;
LLVM_BUILD_OP(SDiv, left, right, res, "div_s", false); LLVM_BUILD_OP(SDiv, left, right, res, "div_s", false);
@ -532,8 +520,7 @@ handle_default:
CHECK_INT_OVERFLOW(I32); CHECK_INT_OVERFLOW(I32);
else else
CHECK_INT_OVERFLOW(I64); CHECK_INT_OVERFLOW(I64);
return compile_rems(comp_ctx, func_ctx, return compile_rems(comp_ctx, func_ctx, left, right, overflow,
left, right, overflow,
is_i32); is_i32);
case INT_REM_U: case INT_REM_U:
LLVM_BUILD_OP(URem, left, right, res, "rem_u", false); LLVM_BUILD_OP(URem, left, right, res, "rem_u", false);
@ -541,7 +528,8 @@ handle_default:
return true; return true;
default: default:
bh_assert(0); bh_assert(0);
return false;; return false;
;
} }
} }
@ -550,8 +538,7 @@ fail:
} }
static LLVMValueRef static LLVMValueRef
compile_int_add(AOTCompContext *comp_ctx, compile_int_add(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
LLVMValueRef left, LLVMValueRef right,
bool is_i32) bool is_i32)
{ {
/* If one of the operands is 0, just return the other */ /* If one of the operands is 0, just return the other */
@ -565,8 +552,7 @@ compile_int_add(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_int_sub(AOTCompContext *comp_ctx, compile_int_sub(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
LLVMValueRef left, LLVMValueRef right,
bool is_i32) bool is_i32)
{ {
/* If the right operand is 0, just return the left */ /* If the right operand is 0, just return the left */
@ -578,8 +564,7 @@ compile_int_sub(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_int_mul(AOTCompContext *comp_ctx, compile_int_mul(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
LLVMValueRef left, LLVMValueRef right,
bool is_i32) bool is_i32)
{ {
/* If one of the operands is 0, just return constant 0 */ /* If one of the operands is 0, just return constant 0 */
@ -592,7 +577,8 @@ compile_int_mul(AOTCompContext *comp_ctx,
static bool static bool
compile_op_int_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, compile_op_int_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
IntArithmetic arith_op, bool is_i32, uint8 **p_frame_ip) IntArithmetic arith_op, bool is_i32,
uint8 **p_frame_ip)
{ {
switch (arith_op) { switch (arith_op) {
case INT_ADD: case INT_ADD:
@ -611,7 +597,8 @@ compile_op_int_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
case INT_DIV_U: case INT_DIV_U:
case INT_REM_S: case INT_REM_S:
case INT_REM_U: case INT_REM_U:
return compile_int_div(comp_ctx, func_ctx, arith_op, is_i32, p_frame_ip); return compile_int_div(comp_ctx, func_ctx, arith_op, is_i32,
p_frame_ip);
default: default:
bh_assert(0); bh_assert(0);
return false; return false;
@ -627,18 +614,17 @@ compile_op_int_bitwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{ {
switch (bitwise_op) { switch (bitwise_op) {
case INT_AND: case INT_AND:
DEF_INT_BINARY_OP(LLVMBuildAnd(comp_ctx->builder, DEF_INT_BINARY_OP(
left, right, "and"), LLVMBuildAnd(comp_ctx->builder, left, right, "and"),
"llvm build and fail."); "llvm build and fail.");
return true; return true;
case INT_OR: case INT_OR:
DEF_INT_BINARY_OP(LLVMBuildOr(comp_ctx->builder, DEF_INT_BINARY_OP(LLVMBuildOr(comp_ctx->builder, left, right, "or"),
left, right, "or"),
"llvm build or fail."); "llvm build or fail.");
return true; return true;
case INT_XOR: case INT_XOR:
DEF_INT_BINARY_OP(LLVMBuildXor(comp_ctx->builder, DEF_INT_BINARY_OP(
left, right, "xor"), LLVMBuildXor(comp_ctx->builder, left, right, "xor"),
"llvm build xor fail."); "llvm build xor fail.");
return true; return true;
default: default:
@ -651,8 +637,7 @@ fail:
} }
static LLVMValueRef static LLVMValueRef
compile_int_shl(AOTCompContext *comp_ctx, compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
LLVMValueRef left, LLVMValueRef right,
bool is_i32) bool is_i32)
{ {
LLVMValueRef res; LLVMValueRef res;
@ -668,9 +653,8 @@ compile_int_shl(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_int_shr_s(AOTCompContext *comp_ctx, compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
LLVMValueRef left, LLVMValueRef right, LLVMValueRef right, bool is_i32)
bool is_i32)
{ {
LLVMValueRef res; LLVMValueRef res;
@ -685,9 +669,8 @@ compile_int_shr_s(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_int_shr_u(AOTCompContext *comp_ctx, compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
LLVMValueRef left, LLVMValueRef right, LLVMValueRef right, bool is_i32)
bool is_i32)
{ {
LLVMValueRef res; LLVMValueRef res;
@ -702,10 +685,8 @@ compile_int_shr_u(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
compile_int_rot(AOTCompContext *comp_ctx, compile_int_rot(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
LLVMValueRef left, LLVMValueRef right, bool is_rotl, bool is_i32)
bool is_rotl,
bool is_i32)
{ {
LLVMValueRef bits_minus_shift_count, res, tmp_l, tmp_r; LLVMValueRef bits_minus_shift_count, res, tmp_l, tmp_r;
char *name = is_rotl ? "rotl" : "rotr"; char *name = is_rotl ? "rotl" : "rotr";
@ -713,12 +694,8 @@ compile_int_rot(AOTCompContext *comp_ctx,
SHIFT_COUNT_MASK; SHIFT_COUNT_MASK;
/* Calculate (bits - shif_count) */ /* Calculate (bits - shif_count) */
LLVM_BUILD_OP(Sub, LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
is_i32 ? I32_32 : I64_64, "bits_minus_shift_count", NULL);
right,
bits_minus_shift_count,
"bits_minus_shift_count",
NULL);
if (is_rotl) { if (is_rotl) {
/* left<<count | left>>(BITS-count) */ /* left<<count | left>>(BITS-count) */
@ -754,14 +731,12 @@ compile_op_int_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
NULL); NULL);
return true; return true;
case INT_ROTL: case INT_ROTL:
DEF_INT_BINARY_OP(compile_int_rot(comp_ctx, left, right, DEF_INT_BINARY_OP(
true, is_i32), compile_int_rot(comp_ctx, left, right, true, is_i32), NULL);
NULL);
return true; return true;
case INT_ROTR: case INT_ROTR:
DEF_INT_BINARY_OP(compile_int_rot(comp_ctx, left, right, DEF_INT_BINARY_OP(
false, is_i32), compile_int_rot(comp_ctx, left, right, false, is_i32), NULL);
NULL);
return true; return true;
default: default:
bh_assert(0); bh_assert(0);
@ -775,16 +750,16 @@ fail:
static bool static bool
is_target_arm(AOTCompContext *comp_ctx) is_target_arm(AOTCompContext *comp_ctx)
{ {
return !strncmp(comp_ctx->target_arch, "arm", 3) || return !strncmp(comp_ctx->target_arch, "arm", 3)
!strncmp(comp_ctx->target_arch, "aarch64", 7) || || !strncmp(comp_ctx->target_arch, "aarch64", 7)
!strncmp(comp_ctx->target_arch, "thumb", 5); || !strncmp(comp_ctx->target_arch, "thumb", 5);
} }
static bool static bool
is_target_x86(AOTCompContext *comp_ctx) is_target_x86(AOTCompContext *comp_ctx)
{ {
return !strncmp(comp_ctx->target_arch, "x86_64", 6) || return !strncmp(comp_ctx->target_arch, "x86_64", 6)
!strncmp(comp_ctx->target_arch, "i386", 4); || !strncmp(comp_ctx->target_arch, "i386", 4);
} }
static bool static bool
@ -821,9 +796,8 @@ is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
* LLVM CodeGen uses FPU Coprocessor registers by default, * LLVM CodeGen uses FPU Coprocessor registers by default,
* so user must specify '--cpu-features=+soft-float' to wamrc if the target * so user must specify '--cpu-features=+soft-float' to wamrc if the target
* doesn't have or enable FPU on arm, x86 or mips. */ * doesn't have or enable FPU on arm, x86 or mips. */
if (is_target_arm(comp_ctx) || if (is_target_arm(comp_ctx) || is_target_x86(comp_ctx)
is_target_x86(comp_ctx) || || is_target_mips(comp_ctx))
is_target_mips(comp_ctx))
ret = strstr(feature_string, "+soft-float") ? true : false; ret = strstr(feature_string, "+soft-float") ? true : false;
else if (is_target_xtensa(comp_ctx)) else if (is_target_xtensa(comp_ctx))
/* Note: /* Note:
@ -832,7 +806,8 @@ is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
* for f64(i.e. double). * for f64(i.e. double).
* 2. LLVM CodeGen uses Floating-Point Coprocessor registers by default, * 2. LLVM CodeGen uses Floating-Point Coprocessor registers by default,
* so user must specify '--cpu-features=-fp' to wamrc if the target * so user must specify '--cpu-features=-fp' to wamrc if the target
* doesn't have or enable Floating-Point Coprocessor Option on xtensa. */ * doesn't have or enable Floating-Point Coprocessor Option on xtensa.
*/
ret = (!is_f32 || strstr(feature_string, "-fp")) ? true : false; ret = (!is_f32 || strstr(feature_string, "-fp")) ? true : false;
else if (is_target_riscv(comp_ctx)) { else if (is_target_riscv(comp_ctx)) {
/* /*
@ -859,91 +834,72 @@ compile_op_float_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
switch (arith_op) { switch (arith_op) {
case FLOAT_ADD: case FLOAT_ADD:
if (is_targeting_soft_float(comp_ctx, is_f32)) if (is_targeting_soft_float(comp_ctx, is_f32))
DEF_FP_BINARY_OP(LLVMBuildFAdd(comp_ctx->builder, left, right, "fadd"), DEF_FP_BINARY_OP(
LLVMBuildFAdd(comp_ctx->builder, left, right, "fadd"),
"llvm build fadd fail."); "llvm build fadd fail.");
else else
DEF_FP_BINARY_OP(call_llvm_float_experimental_constrained_intrinsic( DEF_FP_BINARY_OP(
comp_ctx, call_llvm_float_experimental_constrained_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, (is_f32 ? "llvm.experimental.constrained.fadd.f32"
(is_f32
? "llvm.experimental.constrained.fadd.f32"
: "llvm.experimental.constrained.fadd.f64"), : "llvm.experimental.constrained.fadd.f64"),
left, left, right, comp_ctx->fp_rounding_mode,
right,
comp_ctx->fp_rounding_mode,
comp_ctx->fp_exception_behavior), comp_ctx->fp_exception_behavior),
NULL); NULL);
return true; return true;
case FLOAT_SUB: case FLOAT_SUB:
if (is_targeting_soft_float(comp_ctx, is_f32)) if (is_targeting_soft_float(comp_ctx, is_f32))
DEF_FP_BINARY_OP(LLVMBuildFSub(comp_ctx->builder, left, right, "fsub"), DEF_FP_BINARY_OP(
LLVMBuildFSub(comp_ctx->builder, left, right, "fsub"),
"llvm build fsub fail."); "llvm build fsub fail.");
else else
DEF_FP_BINARY_OP(call_llvm_float_experimental_constrained_intrinsic( DEF_FP_BINARY_OP(
comp_ctx, call_llvm_float_experimental_constrained_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, (is_f32 ? "llvm.experimental.constrained.fsub.f32"
(is_f32
? "llvm.experimental.constrained.fsub.f32"
: "llvm.experimental.constrained.fsub.f64"), : "llvm.experimental.constrained.fsub.f64"),
left, left, right, comp_ctx->fp_rounding_mode,
right,
comp_ctx->fp_rounding_mode,
comp_ctx->fp_exception_behavior), comp_ctx->fp_exception_behavior),
NULL); NULL);
return true; return true;
case FLOAT_MUL: case FLOAT_MUL:
if (is_targeting_soft_float(comp_ctx, is_f32)) if (is_targeting_soft_float(comp_ctx, is_f32))
DEF_FP_BINARY_OP(LLVMBuildFMul(comp_ctx->builder, left, right, "fmul"), DEF_FP_BINARY_OP(
LLVMBuildFMul(comp_ctx->builder, left, right, "fmul"),
"llvm build fmul fail."); "llvm build fmul fail.");
else else
DEF_FP_BINARY_OP(call_llvm_float_experimental_constrained_intrinsic( DEF_FP_BINARY_OP(
comp_ctx, call_llvm_float_experimental_constrained_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, (is_f32 ? "llvm.experimental.constrained.fmul.f32"
(is_f32
? "llvm.experimental.constrained.fmul.f32"
: "llvm.experimental.constrained.fmul.f64"), : "llvm.experimental.constrained.fmul.f64"),
left, left, right, comp_ctx->fp_rounding_mode,
right,
comp_ctx->fp_rounding_mode,
comp_ctx->fp_exception_behavior), comp_ctx->fp_exception_behavior),
NULL); NULL);
return true; return true;
case FLOAT_DIV: case FLOAT_DIV:
if (is_targeting_soft_float(comp_ctx, is_f32)) if (is_targeting_soft_float(comp_ctx, is_f32))
DEF_FP_BINARY_OP(LLVMBuildFDiv(comp_ctx->builder, left, right, "fdiv"), DEF_FP_BINARY_OP(
LLVMBuildFDiv(comp_ctx->builder, left, right, "fdiv"),
"llvm build fdiv fail."); "llvm build fdiv fail.");
else else
DEF_FP_BINARY_OP(call_llvm_float_experimental_constrained_intrinsic( DEF_FP_BINARY_OP(
comp_ctx, call_llvm_float_experimental_constrained_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, (is_f32 ? "llvm.experimental.constrained.fdiv.f32"
(is_f32
? "llvm.experimental.constrained.fdiv.f32"
: "llvm.experimental.constrained.fdiv.f64"), : "llvm.experimental.constrained.fdiv.f64"),
left, left, right, comp_ctx->fp_rounding_mode,
right,
comp_ctx->fp_rounding_mode,
comp_ctx->fp_exception_behavior), comp_ctx->fp_exception_behavior),
NULL); NULL);
return true; return true;
case FLOAT_MIN: case FLOAT_MIN:
DEF_FP_BINARY_OP(compile_op_float_min_max(comp_ctx, DEF_FP_BINARY_OP(compile_op_float_min_max(
func_ctx, comp_ctx, func_ctx, is_f32, left, right, true),
is_f32,
left,
right,
true),
NULL); NULL);
return true; return true;
case FLOAT_MAX: case FLOAT_MAX:
DEF_FP_BINARY_OP(compile_op_float_min_max(comp_ctx, DEF_FP_BINARY_OP(compile_op_float_min_max(comp_ctx, func_ctx,
func_ctx, is_f32, left, right,
is_f32,
left,
right,
false), false),
NULL); NULL);
@ -959,10 +915,8 @@ fail:
static LLVMValueRef static LLVMValueRef
call_llvm_float_math_intrinsic(AOTCompContext *comp_ctx, call_llvm_float_math_intrinsic(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_f32,
bool is_f32, const char *intrinsic, ...)
const char *intrinsic,
...)
{ {
va_list param_value_list; va_list param_value_list;
LLVMValueRef ret; LLVMValueRef ret;
@ -986,11 +940,9 @@ compile_op_float_math(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{ {
switch (math_op) { switch (math_op) {
case FLOAT_ABS: case FLOAT_ABS:
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.fabs.f32" : "llvm.fabs.f64",
is_f32 ? "llvm.fabs.f32" :
"llvm.fabs.f64",
operand), operand),
NULL); NULL);
return true; return true;
@ -1000,61 +952,48 @@ compile_op_float_math(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return true; return true;
case FLOAT_CEIL: case FLOAT_CEIL:
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.ceil.f32" : "llvm.ceil.f64",
is_f32 ? "llvm.ceil.f32" :
"llvm.ceil.f64",
operand), operand),
NULL); NULL);
return true; return true;
case FLOAT_FLOOR: case FLOAT_FLOOR:
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.floor.f32" : "llvm.floor.f64",
is_f32 ? "llvm.floor.f32":
"llvm.floor.f64",
operand), operand),
NULL); NULL);
return true; return true;
case FLOAT_TRUNC: case FLOAT_TRUNC:
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.trunc.f32" : "llvm.trunc.f64",
is_f32 ? "llvm.trunc.f32" :
"llvm.trunc.f64",
operand), operand),
NULL); NULL);
return true; return true;
case FLOAT_NEAREST: case FLOAT_NEAREST:
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.rint.f32" : "llvm.rint.f64",
is_f32 ? "llvm.rint.f32" :
"llvm.rint.f64",
operand), operand),
NULL); NULL);
return true; return true;
case FLOAT_SQRT: case FLOAT_SQRT:
if (is_targeting_soft_float(comp_ctx, is_f32) if (is_targeting_soft_float(comp_ctx, is_f32)
|| comp_ctx->disable_llvm_intrinsics) || comp_ctx->disable_llvm_intrinsics)
DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, is_f32 ? "llvm.sqrt.f32" : "llvm.sqrt.f64",
is_f32 ? "llvm.sqrt.f32" :
"llvm.sqrt.f64",
operand), operand),
NULL); NULL);
else else
DEF_FP_UNARY_OP(call_llvm_libm_experimental_constrained_intrinsic( DEF_FP_UNARY_OP(
comp_ctx, call_llvm_libm_experimental_constrained_intrinsic(
func_ctx, comp_ctx, func_ctx, is_f32,
is_f32, (is_f32 ? "llvm.experimental.constrained.sqrt.f32"
(is_f32
? "llvm.experimental.constrained.sqrt.f32"
: "llvm.experimental.constrained.sqrt.f64"), : "llvm.experimental.constrained.sqrt.f64"),
operand, operand, comp_ctx->fp_rounding_mode,
comp_ctx->fp_rounding_mode,
comp_ctx->fp_exception_behavior), comp_ctx->fp_exception_behavior),
NULL); NULL);
return true; return true;
@ -1077,15 +1016,10 @@ compile_float_copysign(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
param_types[0] = param_types[1] = ret_type = is_f32 ? F32_TYPE : F64_TYPE; param_types[0] = param_types[1] = ret_type = is_f32 ? F32_TYPE : F64_TYPE;
DEF_FP_BINARY_OP(aot_call_llvm_intrinsic(comp_ctx, DEF_FP_BINARY_OP(aot_call_llvm_intrinsic(
func_ctx, comp_ctx, func_ctx,
is_f32 ? "llvm.copysign.f32" : is_f32 ? "llvm.copysign.f32" : "llvm.copysign.f64",
"llvm.copysign.f64", ret_type, param_types, 2, left, right),
ret_type,
param_types,
2,
left,
right),
NULL); NULL);
return true; return true;
@ -1130,17 +1064,21 @@ aot_compile_op_i64_popcnt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
bool bool
aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx,
IntArithmetic arith_op, uint8 **p_frame_ip) AOTFuncContext *func_ctx, IntArithmetic arith_op,
uint8 **p_frame_ip)
{ {
return compile_op_int_arithmetic(comp_ctx, func_ctx, arith_op, true, p_frame_ip); return compile_op_int_arithmetic(comp_ctx, func_ctx, arith_op, true,
p_frame_ip);
} }
bool bool
aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx,
IntArithmetic arith_op, uint8 **p_frame_ip) AOTFuncContext *func_ctx, IntArithmetic arith_op,
uint8 **p_frame_ip)
{ {
return compile_op_int_arithmetic(comp_ctx, func_ctx, arith_op, false, p_frame_ip); return compile_op_int_arithmetic(comp_ctx, func_ctx, arith_op, false,
p_frame_ip);
} }
bool bool
@ -1212,4 +1150,3 @@ aot_compile_op_f64_copysign(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
return compile_float_copysign(comp_ctx, func_ctx, false); return compile_float_copysign(comp_ctx, func_ctx, false);
} }

View File

@ -31,12 +31,14 @@ bool
aot_compile_op_i64_popcnt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_op_i64_popcnt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
bool bool
aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx,
IntArithmetic arith_op, uint8 **p_frame_ip); AOTFuncContext *func_ctx, IntArithmetic arith_op,
uint8 **p_frame_ip);
bool bool
aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx,
IntArithmetic arith_op, uint8 **p_frame_ip); AOTFuncContext *func_ctx, IntArithmetic arith_op,
uint8 **p_frame_ip);
bool bool
aot_compile_op_i32_bitwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i32_bitwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@ -63,11 +65,13 @@ aot_compile_op_f64_math(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
FloatMath math_op); FloatMath math_op);
bool bool
aot_compile_op_f32_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_arithmetic(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op); FloatArithmetic arith_op);
bool bool
aot_compile_op_f64_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_arithmetic(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op); FloatArithmetic arith_op);
bool bool
@ -81,4 +85,3 @@ aot_compile_op_f64_copysign(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
#endif #endif
#endif /* end of _AOT_EMIT_NUMBERIC_H_ */ #endif /* end of _AOT_EMIT_NUMBERIC_H_ */

View File

@ -7,8 +7,7 @@
static bool static bool
pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef *p_value, LLVMValueRef *p_value, bool is_32, uint8 *p_type)
bool is_32, uint8 *p_type)
{ {
AOTValue *aot_value; AOTValue *aot_value;
uint8 type; uint8 type;
@ -22,14 +21,14 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
aot_value = aot_value_stack_pop aot_value =
(&func_ctx->block_stack.block_list_end->value_stack); aot_value_stack_pop(&func_ctx->block_stack.block_list_end->value_stack);
type = aot_value->type; type = aot_value->type;
if (aot_value->type == VALUE_TYPE_I1) { if (aot_value->type == VALUE_TYPE_I1) {
if (!(aot_value->value = if (!(aot_value->value =
LLVMBuildZExt(comp_ctx->builder, aot_value->value, LLVMBuildZExt(comp_ctx->builder, aot_value->value, I32_TYPE,
I32_TYPE, "val_s_ext"))) { "val_s_ext"))) {
aot_set_last_error("llvm build sign ext failed."); aot_set_last_error("llvm build sign ext failed.");
return false; return false;
} }
@ -55,8 +54,7 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* !is_32: i64, f64 */ /* !is_32: i64, f64 */
if (!is_32 if (!is_32 && !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
&& !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
aot_set_last_error("invalid WASM stack data type."); aot_set_last_error("invalid WASM stack data type.");
return false; return false;
} }
@ -64,7 +62,6 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return true; return true;
} }
bool bool
aot_compile_op_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool is_drop_32) bool is_drop_32)
@ -84,8 +81,10 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
POP_COND(cond); POP_COND(cond);
if (!pop_value_from_wasm_stack(comp_ctx, func_ctx, &val2, is_select_32, &val2_type) if (!pop_value_from_wasm_stack(comp_ctx, func_ctx, &val2, is_select_32,
|| !pop_value_from_wasm_stack(comp_ctx, func_ctx, &val1, is_select_32, &val1_type)) &val2_type)
|| !pop_value_from_wasm_stack(comp_ctx, func_ctx, &val1, is_select_32,
&val1_type))
return false; return false;
if (val1_type != val2_type) { if (val1_type != val2_type) {
@ -93,9 +92,8 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
if (!(selected = LLVMBuildSelect(comp_ctx->builder, if (!(selected =
cond, val1, val2, LLVMBuildSelect(comp_ctx->builder, cond, val1, val2, "select"))) {
"select"))) {
aot_set_last_error("llvm build select failed."); aot_set_last_error("llvm build select failed.");
return false; return false;
} }
@ -107,4 +105,3 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
fail: fail:
return false; return false;
} }

View File

@ -20,10 +20,8 @@ bool
aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool is_select_32); bool is_select_32);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif
#endif /* end of _AOT_EMIT_PARAMETRIC_H_ */ #endif /* end of _AOT_EMIT_PARAMETRIC_H_ */

View File

@ -7,11 +7,9 @@
#include "aot_emit_exception.h" #include "aot_emit_exception.h"
#include "../aot/aot_runtime.h" #include "../aot/aot_runtime.h"
uint64 uint64
get_tbl_inst_offset(const AOTCompContext *comp_ctx, get_tbl_inst_offset(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, uint32 tbl_idx)
uint32 tbl_idx)
{ {
uint64 offset = 0, i = 0; uint64 offset = 0, i = 0;
AOTImportTable *imp_tbls = comp_ctx->comp_data->import_tables; AOTImportTable *imp_tbls = comp_ctx->comp_data->import_tables;
@ -49,8 +47,7 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx,
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
LLVMValueRef LLVMValueRef
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMValueRef offset, tbl_inst; LLVMValueRef offset, tbl_inst;
@ -73,8 +70,7 @@ fail:
} }
bool bool
aot_compile_op_elem_drop(AOTCompContext *comp_ctx, aot_compile_op_elem_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_seg_idx) uint32 tbl_seg_idx)
{ {
LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type; LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
@ -106,10 +102,8 @@ fail:
} }
static bool static bool
aot_check_table_access(AOTCompContext *comp_ctx, aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 tbl_idx, LLVMValueRef elem_idx)
uint32 tbl_idx,
LLVMValueRef elem_idx)
{ {
LLVMValueRef offset, tbl_sz, cmp_elem_idx; LLVMValueRef offset, tbl_sz, cmp_elem_idx;
LLVMBasicBlockRef check_elem_idx_succ; LLVMBasicBlockRef check_elem_idx_succ;
@ -166,8 +160,7 @@ fail:
} }
bool bool
aot_compile_op_table_get(AOTCompContext *comp_ctx, aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMValueRef elem_idx, offset, table_elem, func_idx; LLVMValueRef elem_idx, offset, table_elem, func_idx;
@ -198,8 +191,8 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx,
} }
/* Load function index */ /* Load function index */
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
1, "table_elem"))) { "table_elem"))) {
HANDLE_FAILURE("LLVMBuildNUWAdd"); HANDLE_FAILURE("LLVMBuildNUWAdd");
goto fail; goto fail;
} }
@ -218,8 +211,7 @@ fail:
} }
bool bool
aot_compile_op_table_set(AOTCompContext *comp_ctx, aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMValueRef val, elem_idx, offset, table_elem; LLVMValueRef val, elem_idx, offset, table_elem;
@ -251,8 +243,8 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx,
} }
/* Load function index */ /* Load function index */
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
1, "table_elem"))) { "table_elem"))) {
HANDLE_FAILURE("LLVMBuildGEP"); HANDLE_FAILURE("LLVMBuildGEP");
goto fail; goto fail;
} }
@ -268,10 +260,8 @@ fail:
} }
bool bool
aot_compile_op_table_init(AOTCompContext *comp_ctx, aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 tbl_idx, uint32 tbl_seg_idx)
uint32 tbl_idx,
uint32 tbl_seg_idx)
{ {
LLVMValueRef func, param_values[6], value; LLVMValueRef func, param_values[6], value;
@ -318,10 +308,8 @@ fail:
} }
bool bool
aot_compile_op_table_copy(AOTCompContext *comp_ctx, aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 src_tbl_idx, uint32 dst_tbl_idx)
uint32 src_tbl_idx,
uint32 dst_tbl_idx)
{ {
LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type; LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
LLVMValueRef func, param_values[6], value; LLVMValueRef func, param_values[6], value;
@ -367,8 +355,7 @@ fail:
} }
bool bool
aot_compile_op_table_size(AOTCompContext *comp_ctx, aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMValueRef offset, tbl_sz; LLVMValueRef offset, tbl_sz;
@ -404,8 +391,7 @@ fail:
} }
bool bool
aot_compile_op_table_grow(AOTCompContext *comp_ctx, aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type; LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
@ -445,8 +431,7 @@ fail:
} }
bool bool
aot_compile_op_table_fill(AOTCompContext *comp_ctx, aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx) uint32 tbl_idx)
{ {
LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type; LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;

View File

@ -14,55 +14,43 @@ extern "C" {
#endif #endif
bool bool
aot_compile_op_elem_drop(AOTCompContext *comp_ctx, aot_compile_op_elem_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_seg_idx); uint32 tbl_seg_idx);
bool bool
aot_compile_op_table_get(AOTCompContext *comp_ctx, aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
bool bool
aot_compile_op_table_set(AOTCompContext *comp_ctx, aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
bool bool
aot_compile_op_table_init(AOTCompContext *comp_ctx, aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 tbl_idx, uint32 tbl_seg_idx);
uint32 tbl_idx,
uint32 tbl_seg_idx);
bool bool
aot_compile_op_table_copy(AOTCompContext *comp_ctx, aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 src_tbl_idx, uint32 dst_tbl_idx);
uint32 src_tbl_idx,
uint32 dst_tbl_idx);
bool bool
aot_compile_op_table_size(AOTCompContext *comp_ctx, aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
bool bool
aot_compile_op_table_grow(AOTCompContext *comp_ctx, aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
bool bool
aot_compile_op_table_fill(AOTCompContext *comp_ctx, aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
uint64 uint64
get_tbl_inst_offset(const AOTCompContext *comp_ctx, get_tbl_inst_offset(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, uint32 tbl_idx);
uint32 tbl_idx);
LLVMValueRef LLVMValueRef
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint32 tbl_idx); uint32 tbl_idx);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -7,7 +7,8 @@
#include "aot_emit_exception.h" #include "aot_emit_exception.h"
#include "../aot/aot_runtime.h" #include "../aot/aot_runtime.h"
#define CHECK_LOCAL(idx) do { \ #define CHECK_LOCAL(idx) \
do { \
if (idx >= func_ctx->aot_func->func_type->param_count \ if (idx >= func_ctx->aot_func->func_type->param_count \
+ func_ctx->aot_func->local_count) { \ + func_ctx->aot_func->local_count) { \
aot_set_last_error("local index out of range"); \ aot_set_last_error("local index out of range"); \
@ -36,8 +37,7 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
CHECK_LOCAL(local_idx); CHECK_LOCAL(local_idx);
snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#"); snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#");
if (!(value = LLVMBuildLoad(comp_ctx->builder, if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->locals[local_idx],
func_ctx->locals[local_idx],
name))) { name))) {
aot_set_last_error("llvm build load fail"); aot_set_last_error("llvm build load fail");
return false; return false;
@ -45,7 +45,8 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
PUSH(value, get_local_type(func_ctx, local_idx)); PUSH(value, get_local_type(func_ctx, local_idx));
aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end; aot_value =
func_ctx->block_stack.block_list_end->value_stack.value_list_end;
aot_value->is_local = true; aot_value->is_local = true;
aot_value->local_idx = local_idx; aot_value->local_idx = local_idx;
return true; return true;
@ -64,8 +65,7 @@ aot_compile_op_set_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
POP(value, get_local_type(func_ctx, local_idx)); POP(value, get_local_type(func_ctx, local_idx));
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(comp_ctx->builder, value,
value,
func_ctx->locals[local_idx])) { func_ctx->locals[local_idx])) {
aot_set_last_error("llvm build store fail"); aot_set_last_error("llvm build store fail");
return false; return false;
@ -91,8 +91,7 @@ aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
POP(value, type); POP(value, type);
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(comp_ctx->builder, value,
value,
func_ctx->locals[local_idx])) { func_ctx->locals[local_idx])) {
aot_set_last_error("llvm build store fail"); aot_set_last_error("llvm build store fail");
return false; return false;
@ -128,14 +127,15 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
global_type = comp_data->import_globals[global_idx].type; global_type = comp_data->import_globals[global_idx].type;
} }
else { else {
global_offset = global_base_offset global_offset =
global_base_offset
+ comp_data->globals[global_idx - import_global_count].data_offset; + comp_data->globals[global_idx - import_global_count].data_offset;
global_type = global_type = comp_data->globals[global_idx - import_global_count].type;
comp_data->globals[global_idx - import_global_count].type;
} }
offset = I32_CONST(global_offset); offset = I32_CONST(global_offset);
if (!(global_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, if (!(global_ptr =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "global_ptr_tmp"))) { &offset, 1, "global_ptr_tmp"))) {
aot_set_last_error("llvm build in bounds gep failed."); aot_set_last_error("llvm build in bounds gep failed.");
return false; return false;
@ -164,15 +164,15 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
break; break;
} }
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr, if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr, ptr_type,
ptr_type, "global_ptr"))) { "global_ptr"))) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
if (!is_set) { if (!is_set) {
if (!(global = LLVMBuildLoad(comp_ctx->builder, if (!(global =
global_ptr, "global"))) { LLVMBuildLoad(comp_ctx->builder, global_ptr, "global"))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
} }
@ -184,23 +184,22 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
POP(global, global_type); POP(global, global_type);
if (is_aux_stack && comp_ctx->enable_aux_stack_check) { if (is_aux_stack && comp_ctx->enable_aux_stack_check) {
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); LLVMBasicBlockRef block_curr =
LLVMGetInsertBlock(comp_ctx->builder);
LLVMBasicBlockRef check_overflow_succ, check_underflow_succ; LLVMBasicBlockRef check_overflow_succ, check_underflow_succ;
LLVMValueRef cmp; LLVMValueRef cmp;
/* Add basic blocks */ /* Add basic blocks */
if (!(check_overflow_succ = if (!(check_overflow_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func,
func_ctx->func,
"check_overflow_succ"))) { "check_overflow_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
} }
LLVMMoveBasicBlockAfter(check_overflow_succ, block_curr); LLVMMoveBasicBlockAfter(check_overflow_succ, block_curr);
if (!(check_underflow_succ = if (!(check_underflow_succ = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, comp_ctx->context, func_ctx->func,
func_ctx->func,
"check_underflow_succ"))) { "check_underflow_succ"))) {
aot_set_last_error("llvm add basic block failed."); aot_set_last_error("llvm add basic block failed.");
return false; return false;
@ -208,37 +207,33 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ); LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ);
/* Check aux stack overflow */ /* Check aux stack overflow */
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE, if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE, global,
global, func_ctx->aux_stack_bound, func_ctx->aux_stack_bound, "cmp"))) {
"cmp"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_AUX_STACK_OVERFLOW,
EXCE_AUX_STACK_OVERFLOW,
true, cmp, check_overflow_succ)) { true, cmp, check_overflow_succ)) {
return false; return false;
} }
/* Check aux stack underflow */ /* Check aux stack underflow */
LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ); LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ);
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, global,
global, func_ctx->aux_stack_bottom, func_ctx->aux_stack_bottom, "cmp"))) {
"cmp"))) {
aot_set_last_error("llvm build icmp failed."); aot_set_last_error("llvm build icmp failed.");
return false; return false;
} }
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_AUX_STACK_UNDERFLOW, EXCE_AUX_STACK_UNDERFLOW, true, cmp,
true, cmp, check_underflow_succ)) { check_underflow_succ)) {
return false; return false;
} }
LLVMPositionBuilderAtEnd(comp_ctx->builder, check_underflow_succ); LLVMPositionBuilderAtEnd(comp_ctx->builder, check_underflow_succ);
} }
if (!(res = LLVMBuildStore(comp_ctx->builder, if (!(res = LLVMBuildStore(comp_ctx->builder, global, global_ptr))) {
global, global_ptr))) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
return false; return false;
} }
@ -264,4 +259,3 @@ aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{ {
return compile_global(comp_ctx, func_ctx, global_idx, true, is_aux_stack); return compile_global(comp_ctx, func_ctx, global_idx, true, is_aux_stack);
} }

View File

@ -37,4 +37,3 @@ aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#endif #endif
#endif /* end of _AOT_EMIT_VARIABLE_H_ */ #endif /* end of _AOT_EMIT_VARIABLE_H_ */

View File

@ -83,13 +83,14 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, AOTFuncType *aot_func_type,
/* Resolve return type of the LLVM function */ /* Resolve return type of the LLVM function */
if (aot_func_type->result_count) if (aot_func_type->result_count)
ret_type = TO_LLVM_TYPE(aot_func_type->types[aot_func_type->param_count]); ret_type =
TO_LLVM_TYPE(aot_func_type->types[aot_func_type->param_count]);
else else
ret_type = VOID_TYPE; ret_type = VOID_TYPE;
/* Resolve function prototype */ /* Resolve function prototype */
if (!(func_type = LLVMFunctionType(ret_type, param_types, if (!(func_type =
param_count, false))) { LLVMFunctionType(ret_type, param_types, param_count, false))) {
aot_set_last_error("create LLVM function type failed."); aot_set_last_error("create LLVM function type failed.");
goto fail; goto fail;
} }
@ -163,13 +164,13 @@ aot_create_func_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_block->param_count = param_count; aot_block->param_count = param_count;
memcpy(aot_block->param_types, aot_func_type->types, param_count); memcpy(aot_block->param_types, aot_func_type->types, param_count);
aot_block->result_count = result_count; aot_block->result_count = result_count;
memcpy(aot_block->result_types, aot_func_type->types + param_count, result_count); memcpy(aot_block->result_types, aot_func_type->types + param_count,
result_count);
aot_block->wasm_code_end = func->code + func->code_size; aot_block->wasm_code_end = func->code + func->code_size;
/* Add function entry block */ /* Add function entry block */
if (!(aot_block->llvm_entry_block = if (!(aot_block->llvm_entry_block = LLVMAppendBasicBlockInContext(
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func, comp_ctx->context, func_ctx->func, "func_begin"))) {
"func_begin"))) {
aot_set_last_error("add LLVM basic block failed."); aot_set_last_error("add LLVM basic block failed.");
goto fail; goto fail;
} }
@ -190,7 +191,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
WASMModule *module = comp_ctx->comp_data->wasm_module; WASMModule *module = comp_ctx->comp_data->wasm_module;
WASMFunction *func = module->functions[func_index]; WASMFunction *func = module->functions[func_index];
LLVMTypeRef bound_check_type; LLVMTypeRef bound_check_type;
bool mem_space_unchanged = (!func->has_op_memory_grow && !func->has_op_func_call) bool mem_space_unchanged =
(!func->has_op_memory_grow && !func->has_op_func_call)
|| (!module->possible_memory_grow); || (!module->possible_memory_grow);
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
bool is_shared_memory; bool is_shared_memory;
@ -213,8 +215,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Currently we only create memory info for memory 0 */ /* Currently we only create memory info for memory 0 */
/* Load memory base address */ /* Load memory base address */
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
is_shared_memory = comp_ctx->comp_data->memories[0].memory_flags & 0x02 is_shared_memory =
? true : false; comp_ctx->comp_data->memories[0].memory_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)); offset = I32_CONST(offsetof(AOTModuleInstance, memories));
@ -231,29 +233,25 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false; return false;
} }
if (!(shared_mem_addr = if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
shared_mem_addr, int8_ptr_type, int8_ptr_type, "shared_mem_addr_ptr"))) {
"shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
/* aot_inst->memories[0] */ /* aot_inst->memories[0] */
if (!(shared_mem_addr = if (!(shared_mem_addr = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, shared_mem_addr, "shared_mem_addr"))) {
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
} }
if (!(shared_mem_addr = if (!(shared_mem_addr =
LLVMBuildBitCast(comp_ctx->builder, LLVMBuildBitCast(comp_ctx->builder, shared_mem_addr,
shared_mem_addr, int8_ptr_type, int8_ptr_type, "shared_mem_addr_ptr"))) {
"shared_mem_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!(shared_mem_addr = if (!(shared_mem_addr = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, shared_mem_addr, "shared_mem_addr"))) {
shared_mem_addr, "shared_mem_addr"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
} }
@ -310,31 +308,27 @@ create_memory_info(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 = func_ctx->mem_info[0].mem_base_addr;
if (!(func_ctx->mem_info[0].mem_base_addr = if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr,
func_ctx->mem_info[0].mem_base_addr,
int8_ptr_type, "mem_base_addr_ptr"))) { int8_ptr_type, "mem_base_addr_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_cur_page_count_addr,
func_ctx->mem_info[0].mem_cur_page_count_addr,
INT32_PTR_TYPE, "mem_cur_page_ptr"))) { INT32_PTR_TYPE, "mem_cur_page_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_data_size_addr = if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr,
func_ctx->mem_info[0].mem_data_size_addr,
INT32_PTR_TYPE, "mem_data_size_ptr"))) { INT32_PTR_TYPE, "mem_data_size_ptr"))) {
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 (mem_space_unchanged) {
if (!(func_ctx->mem_info[0].mem_base_addr = if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr,
func_ctx->mem_info[0].mem_base_addr,
"mem_base_addr"))) { "mem_base_addr"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
@ -346,9 +340,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
} }
if (!(func_ctx->mem_info[0].mem_data_size_addr = if (!(func_ctx->mem_info[0].mem_data_size_addr = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_data_size_addr,
func_ctx->mem_info[0].mem_data_size_addr,
"mem_data_size"))) { "mem_data_size"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
@ -358,9 +351,8 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else if (is_shared_memory) { else 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 */ we can load the value here */
if (!(func_ctx->mem_info[0].mem_base_addr = if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_base_addr,
func_ctx->mem_info[0].mem_base_addr,
"mem_base_addr"))) { "mem_base_addr"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; return false;
@ -369,20 +361,20 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#endif #endif
bound_check_type = (comp_ctx->pointer_size == sizeof(uint64)) bound_check_type = (comp_ctx->pointer_size == sizeof(uint64))
? INT64_PTR_TYPE : INT32_PTR_TYPE; ? INT64_PTR_TYPE
: INT32_PTR_TYPE;
/* Load memory bound check constants */ /* Load memory bound check constants */
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_1byte)
- offsetof(AOTMemoryInstance, memory_data.ptr)); - offsetof(AOTMemoryInstance, memory_data.ptr));
if (!(func_ctx->mem_info[0].mem_bound_check_1byte = if (!(func_ctx->mem_info[0].mem_bound_check_1byte =
LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, LLVMBuildInBoundsGEP(comp_ctx->builder, 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 = if (!(func_ctx->mem_info[0].mem_bound_check_1byte = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_1byte,
func_ctx->mem_info[0].mem_bound_check_1byte,
bound_check_type, "bound_check_1byte_ptr"))) { bound_check_type, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
@ -400,14 +392,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_2bytes)
- offsetof(AOTMemoryInstance, memory_data.ptr)); - offsetof(AOTMemoryInstance, memory_data.ptr));
if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = if (!(func_ctx->mem_info[0].mem_bound_check_2bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, LLVMBuildInBoundsGEP(comp_ctx->builder, 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 = if (!(func_ctx->mem_info[0].mem_bound_check_2bytes = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_2bytes,
func_ctx->mem_info[0].mem_bound_check_2bytes,
bound_check_type, "bound_check_2bytes_ptr"))) { bound_check_type, "bound_check_2bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
@ -425,14 +416,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_4bytes)
- offsetof(AOTMemoryInstance, memory_data.ptr)); - offsetof(AOTMemoryInstance, memory_data.ptr));
if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = if (!(func_ctx->mem_info[0].mem_bound_check_4bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, LLVMBuildInBoundsGEP(comp_ctx->builder, 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 = if (!(func_ctx->mem_info[0].mem_bound_check_4bytes = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_4bytes,
func_ctx->mem_info[0].mem_bound_check_4bytes,
bound_check_type, "bound_check_4bytes_ptr"))) { bound_check_type, "bound_check_4bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
@ -450,14 +440,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_8bytes)
- offsetof(AOTMemoryInstance, memory_data.ptr)); - offsetof(AOTMemoryInstance, memory_data.ptr));
if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = if (!(func_ctx->mem_info[0].mem_bound_check_8bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, LLVMBuildInBoundsGEP(comp_ctx->builder, 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 = if (!(func_ctx->mem_info[0].mem_bound_check_8bytes = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_8bytes,
func_ctx->mem_info[0].mem_bound_check_8bytes,
bound_check_type, "bound_check_8bytes_ptr"))) { bound_check_type, "bound_check_8bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
@ -475,14 +464,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes) offset = I32_CONST(offsetof(AOTMemoryInstance, mem_bound_check_16bytes)
- offsetof(AOTMemoryInstance, memory_data.ptr)); - offsetof(AOTMemoryInstance, memory_data.ptr));
if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = if (!(func_ctx->mem_info[0].mem_bound_check_16bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, LLVMBuildInBoundsGEP(comp_ctx->builder, mem_info_base, &offset, 1,
&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 = if (!(func_ctx->mem_info[0].mem_bound_check_16bytes = LLVMBuildBitCast(
LLVMBuildBitCast(comp_ctx->builder, comp_ctx->builder, func_ctx->mem_info[0].mem_bound_check_16bytes,
func_ctx->mem_info[0].mem_bound_check_16bytes,
bound_check_type, "bound_check_16bytes_ptr"))) { bound_check_type, "bound_check_16bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
@ -506,10 +494,8 @@ create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
LLVMValueRef offset; LLVMValueRef offset;
offset = I32_CONST(offsetof(AOTModuleInstance, cur_exception)); offset = I32_CONST(offsetof(AOTModuleInstance, cur_exception));
func_ctx->cur_exception = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->cur_exception = LLVMBuildInBoundsGEP(
func_ctx->aot_inst, comp_ctx->builder, func_ctx->aot_inst, &offset, 1, "cur_execption");
&offset, 1,
"cur_execption");
if (!func_ctx->cur_exception) { if (!func_ctx->cur_exception) {
aot_set_last_error("llvm build in bounds gep failed."); aot_set_last_error("llvm build in bounds gep failed.");
return false; return false;
@ -518,16 +504,14 @@ create_cur_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
static bool static bool
create_func_type_indexes(AOTCompContext *comp_ctx, create_func_type_indexes(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
LLVMValueRef offset, func_type_indexes_ptr; LLVMValueRef offset, func_type_indexes_ptr;
LLVMTypeRef int32_ptr_type; LLVMTypeRef int32_ptr_type;
offset = I32_CONST(offsetof(AOTModuleInstance, func_type_indexes.ptr)); offset = I32_CONST(offsetof(AOTModuleInstance, func_type_indexes.ptr));
func_type_indexes_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_type_indexes_ptr =
func_ctx->aot_inst, LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, 1,
&offset, 1,
"func_type_indexes_ptr"); "func_type_indexes_ptr");
if (!func_type_indexes_ptr) { if (!func_type_indexes_ptr) {
aot_set_last_error("llvm build add failed."); aot_set_last_error("llvm build add failed.");
@ -539,18 +523,16 @@ create_func_type_indexes(AOTCompContext *comp_ctx,
return false; return false;
} }
func_ctx->func_type_indexes = LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_type_indexes =
func_type_indexes_ptr, LLVMBuildBitCast(comp_ctx->builder, func_type_indexes_ptr,
int32_ptr_type, int32_ptr_type, "func_type_indexes_tmp");
"func_type_indexes_tmp");
if (!func_ctx->func_type_indexes) { if (!func_ctx->func_type_indexes) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
func_ctx->func_type_indexes = LLVMBuildLoad(comp_ctx->builder, func_ctx->func_type_indexes = LLVMBuildLoad(
func_ctx->func_type_indexes, comp_ctx->builder, func_ctx->func_type_indexes, "func_type_indexes");
"func_type_indexes");
if (!func_ctx->func_type_indexes) { if (!func_ctx->func_type_indexes) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
@ -564,28 +546,29 @@ create_func_ptrs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
LLVMValueRef offset; LLVMValueRef offset;
offset = I32_CONST(offsetof(AOTModuleInstance, func_ptrs)); offset = I32_CONST(offsetof(AOTModuleInstance, func_ptrs));
func_ctx->func_ptrs = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs = LLVMBuildInBoundsGEP(
func_ctx->aot_inst, comp_ctx->builder, func_ctx->aot_inst, &offset, 1, "func_ptrs_offset");
&offset, 1, "func_ptrs_offset");
if (!func_ctx->func_ptrs) { if (!func_ctx->func_ptrs) {
aot_set_last_error("llvm build in bounds gep failed."); aot_set_last_error("llvm build in bounds gep failed.");
return false; return false;
} }
func_ctx->func_ptrs = LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs, func_ctx->func_ptrs =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs,
comp_ctx->exec_env_type, "func_ptrs_tmp"); comp_ctx->exec_env_type, "func_ptrs_tmp");
if (!func_ctx->func_ptrs) { if (!func_ctx->func_ptrs) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
func_ctx->func_ptrs = LLVMBuildLoad(comp_ctx->builder, func_ctx->func_ptrs, func_ctx->func_ptrs =
"func_ptrs_ptr"); LLVMBuildLoad(comp_ctx->builder, func_ctx->func_ptrs, "func_ptrs_ptr");
if (!func_ctx->func_ptrs) { if (!func_ctx->func_ptrs) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
} }
func_ctx->func_ptrs = LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs, func_ctx->func_ptrs =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->func_ptrs,
comp_ctx->exec_env_type, "func_ptrs"); comp_ctx->exec_env_type, "func_ptrs");
if (!func_ctx->func_ptrs) { if (!func_ctx->func_ptrs) {
aot_set_last_error("llvm build bit cast failed."); aot_set_last_error("llvm build bit cast failed.");
@ -617,10 +600,10 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
uint32 i, j = 0; uint32 i, j = 0;
/* Allocate memory for the function context */ /* Allocate memory for the function context */
size = offsetof(AOTFuncContext, locals) + sizeof(LLVMValueRef) * size = offsetof(AOTFuncContext, locals)
((uint64)aot_func_type->param_count + func->local_count); + sizeof(LLVMValueRef)
if (size >= UINT32_MAX * ((uint64)aot_func_type->param_count + func->local_count);
|| !(func_ctx = wasm_runtime_malloc((uint32)size))) { if (size >= UINT32_MAX || !(func_ctx = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
@ -634,8 +617,8 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail; goto fail;
/* Create function's first AOTBlock */ /* Create function's first AOTBlock */
if (!(aot_block = aot_create_func_block(comp_ctx, func_ctx, if (!(aot_block =
func, aot_func_type))) aot_create_func_block(comp_ctx, func_ctx, func, aot_func_type)))
goto fail; goto fail;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
@ -660,8 +643,8 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
} }
/* Load aot inst */ /* Load aot inst */
if (!(func_ctx->aot_inst = LLVMBuildLoad(comp_ctx->builder, if (!(func_ctx->aot_inst =
aot_inst_addr, "aot_inst"))) { LLVMBuildLoad(comp_ctx->builder, aot_inst_addr, "aot_inst"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
goto fail; goto fail;
} }
@ -686,84 +669,76 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail; goto fail;
} }
if (!(func_ctx->argv_buf = LLVMBuildLoad(comp_ctx->builder, if (!(func_ctx->argv_buf =
argv_buf_addr, "argv_buf"))) { LLVMBuildLoad(comp_ctx->builder, argv_buf_addr, "argv_buf"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
goto fail; goto fail;
} }
/* Get native stack boundary address */ /* Get native stack boundary address */
if (!(stack_bound_addr = if (!(stack_bound_addr = LLVMBuildInBoundsGEP(
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, comp_ctx->builder, func_ctx->exec_env, &stack_bound_offset, 1,
&stack_bound_offset, 1, "stack_bound_addr"))) { "stack_bound_addr"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
goto fail; goto fail;
} }
if (!(func_ctx->native_stack_bound = if (!(func_ctx->native_stack_bound = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, stack_bound_addr, "native_stack_bound"))) {
stack_bound_addr, "native_stack_bound"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
goto fail; goto fail;
} }
/* Get aux stack boundary address */ /* Get aux stack boundary address */
if (!(aux_stack_bound_addr = if (!(aux_stack_bound_addr = LLVMBuildInBoundsGEP(
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, comp_ctx->builder, func_ctx->exec_env, &aux_stack_bound_offset, 1,
&aux_stack_bound_offset, 1,
"aux_stack_bound_addr"))) { "aux_stack_bound_addr"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
goto fail; goto fail;
} }
if (!(aux_stack_bound_addr = if (!(aux_stack_bound_addr =
LLVMBuildBitCast(comp_ctx->builder, LLVMBuildBitCast(comp_ctx->builder, aux_stack_bound_addr,
aux_stack_bound_addr,
INT32_PTR_TYPE, "aux_stack_bound_ptr"))) { INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
goto fail; goto fail;
} }
if (!(func_ctx->aux_stack_bound = if (!(func_ctx->aux_stack_bound = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, aux_stack_bound_addr, "aux_stack_bound"))) {
aux_stack_bound_addr, "aux_stack_bound"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
goto fail; goto fail;
} }
/* Get aux stack bottom address */ /* Get aux stack bottom address */
if (!(aux_stack_bottom_addr = if (!(aux_stack_bottom_addr = LLVMBuildInBoundsGEP(
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, comp_ctx->builder, func_ctx->exec_env, &aux_stack_bottom_offset,
&aux_stack_bottom_offset, 1, 1, "aux_stack_bottom_addr"))) {
"aux_stack_bottom_addr"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
goto fail; goto fail;
} }
if (!(aux_stack_bottom_addr = if (!(aux_stack_bottom_addr =
LLVMBuildBitCast(comp_ctx->builder, LLVMBuildBitCast(comp_ctx->builder, aux_stack_bottom_addr,
aux_stack_bottom_addr,
INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) { INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
goto fail; goto fail;
} }
if (!(func_ctx->aux_stack_bottom = if (!(func_ctx->aux_stack_bottom = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, comp_ctx->builder, aux_stack_bottom_addr, "aux_stack_bottom"))) {
aux_stack_bottom_addr, "aux_stack_bottom"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
goto fail; goto fail;
} }
if (!(native_symbol_addr = if (!(native_symbol_addr = LLVMBuildInBoundsGEP(
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, comp_ctx->builder, func_ctx->exec_env, &native_symbol_offset, 1,
&native_symbol_offset, 1, "native_symbol_addr"))) { "native_symbol_addr"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
goto fail; goto fail;
} }
if (!(func_ctx->native_symbol = if (!(func_ctx->native_symbol = LLVMBuildLoad(
LLVMBuildLoad(comp_ctx->builder, native_symbol_addr, comp_ctx->builder, native_symbol_addr, "native_symbol_tmp"))) {
"native_symbol_tmp"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
goto fail; goto fail;
} }
@ -779,14 +754,12 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
snprintf(local_name, sizeof(local_name), "l%d", i); snprintf(local_name, sizeof(local_name), "l%d", i);
func_ctx->locals[i] = func_ctx->locals[i] =
LLVMBuildAlloca(comp_ctx->builder, LLVMBuildAlloca(comp_ctx->builder,
TO_LLVM_TYPE(aot_func_type->types[i]), TO_LLVM_TYPE(aot_func_type->types[i]), local_name);
local_name);
if (!func_ctx->locals[i]) { if (!func_ctx->locals[i]) {
aot_set_last_error("llvm build alloca failed."); aot_set_last_error("llvm build alloca failed.");
goto fail; goto fail;
} }
if (!LLVMBuildStore(comp_ctx->builder, if (!LLVMBuildStore(comp_ctx->builder, LLVMGetParam(func_ctx->func, j),
LLVMGetParam(func_ctx->func, j),
func_ctx->locals[i])) { func_ctx->locals[i])) {
aot_set_last_error("llvm build store failed."); aot_set_last_error("llvm build store failed.");
goto fail; goto fail;
@ -837,8 +810,9 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
} }
if (aot_func_type->param_count + func->local_count > 0) { if (aot_func_type->param_count + func->local_count > 0) {
func_ctx->last_alloca = func_ctx->locals[aot_func_type->param_count func_ctx->last_alloca =
+ func->local_count - 1]; func_ctx
->locals[aot_func_type->param_count + func->local_count - 1];
if (!(func_ctx->last_alloca = if (!(func_ctx->last_alloca =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->last_alloca, LLVMBuildBitCast(comp_ctx->builder, func_ctx->last_alloca,
INT8_PTR_TYPE, "stack_ptr"))) { INT8_PTR_TYPE, "stack_ptr"))) {
@ -847,8 +821,8 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
} }
} }
else { else {
if (!(func_ctx->last_alloca = LLVMBuildAlloca(comp_ctx->builder, INT8_TYPE, if (!(func_ctx->last_alloca =
"stack_ptr"))) { LLVMBuildAlloca(comp_ctx->builder, INT8_TYPE, "stack_ptr"))) {
aot_set_last_error("llvm build alloca failed."); aot_set_last_error("llvm build alloca failed.");
goto fail; goto fail;
} }
@ -924,8 +898,8 @@ aot_create_func_contexts(AOTCompData *comp_data, AOTCompContext *comp_ctx)
/* Create each function context */ /* Create each function context */
for (i = 0; i < comp_data->func_count; i++) { for (i = 0; i < comp_data->func_count; i++) {
AOTFunc *func = comp_data->funcs[i]; AOTFunc *func = comp_data->funcs[i];
if (!(func_ctxes[i] = aot_create_func_context(comp_data, comp_ctx, if (!(func_ctxes[i] =
func, i))) { aot_create_func_context(comp_data, comp_ctx, func, i))) {
aot_destroy_func_contexts(func_ctxes, comp_data->func_count); aot_destroy_func_contexts(func_ctxes, comp_data->func_count);
return NULL; return NULL;
} }
@ -958,8 +932,10 @@ aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context)
basic_types->int16_ptr_type = LLVMPointerType(basic_types->int16_type, 0); basic_types->int16_ptr_type = LLVMPointerType(basic_types->int16_type, 0);
basic_types->int32_ptr_type = LLVMPointerType(basic_types->int32_type, 0); basic_types->int32_ptr_type = LLVMPointerType(basic_types->int32_type, 0);
basic_types->int64_ptr_type = LLVMPointerType(basic_types->int64_type, 0); basic_types->int64_ptr_type = LLVMPointerType(basic_types->int64_type, 0);
basic_types->float32_ptr_type = LLVMPointerType(basic_types->float32_type, 0); basic_types->float32_ptr_type =
basic_types->float64_ptr_type = LLVMPointerType(basic_types->float64_type, 0); LLVMPointerType(basic_types->float32_type, 0);
basic_types->float64_ptr_type =
LLVMPointerType(basic_types->float64_type, 0);
basic_types->i8x16_vec_type = LLVMVectorType(basic_types->int8_type, 16); basic_types->i8x16_vec_type = LLVMVectorType(basic_types->int8_type, 16);
basic_types->i16x8_vec_type = LLVMVectorType(basic_types->int16_type, 8); basic_types->i16x8_vec_type = LLVMVectorType(basic_types->int16_type, 8);
@ -976,23 +952,17 @@ aot_set_llvm_basic_types(AOTLLVMTypes *basic_types, LLVMContextRef context)
basic_types->funcref_type = LLVMInt32TypeInContext(context); basic_types->funcref_type = LLVMInt32TypeInContext(context);
basic_types->externref_type = LLVMInt32TypeInContext(context); basic_types->externref_type = LLVMInt32TypeInContext(context);
return (basic_types->int8_ptr_type return (basic_types->int8_ptr_type && basic_types->int8_pptr_type
&& basic_types->int8_pptr_type && basic_types->int16_ptr_type && basic_types->int32_ptr_type
&& basic_types->int16_ptr_type && basic_types->int64_ptr_type && basic_types->float32_ptr_type
&& basic_types->int32_ptr_type && basic_types->float64_ptr_type && basic_types->i8x16_vec_type
&& basic_types->int64_ptr_type && basic_types->i16x8_vec_type && basic_types->i32x4_vec_type
&& basic_types->float32_ptr_type && basic_types->i64x2_vec_type && basic_types->f32x4_vec_type
&& basic_types->float64_ptr_type && basic_types->f64x2_vec_type && basic_types->i1x2_vec_type
&& basic_types->i8x16_vec_type && basic_types->meta_data_type && basic_types->funcref_type
&& basic_types->i16x8_vec_type && basic_types->externref_type)
&& basic_types->i32x4_vec_type ? true
&& basic_types->i64x2_vec_type : false;
&& basic_types->f32x4_vec_type
&& basic_types->f64x2_vec_type
&& basic_types->i1x2_vec_type
&& basic_types->meta_data_type
&& basic_types->funcref_type
&& basic_types->externref_type) ? true : false;
} }
static bool static bool
@ -1088,6 +1058,7 @@ typedef struct ArchItem {
bool support_eb; bool support_eb;
} ArchItem; } ArchItem;
/* clang-format off */
static ArchItem valid_archs[] = { static ArchItem valid_archs[] = {
{ "x86_64", false }, { "x86_64", false },
{ "i386", false }, { "i386", false },
@ -1158,6 +1129,7 @@ static const char *valid_abis[] = {
"lp64f", "lp64f",
"lp64d" "lp64d"
}; };
/* clang-format on */
static void static void
print_supported_targets() print_supported_targets()
@ -1194,7 +1166,8 @@ check_target_arch(const char *target_arch)
support_eb = valid_archs[i].support_eb; support_eb = valid_archs[i].support_eb;
if (!strncmp(target_arch, arch, strlen(arch)) if (!strncmp(target_arch, arch, strlen(arch))
&& ((support_eb && (!strcmp(target_arch + strlen(arch), "eb") && ((support_eb
&& (!strcmp(target_arch + strlen(arch), "eb")
|| !strcmp(target_arch + strlen(arch), ""))) || !strcmp(target_arch + strlen(arch), "")))
|| (!support_eb && !strcmp(target_arch + strlen(arch), "")))) { || (!support_eb && !strcmp(target_arch + strlen(arch), "")))) {
return true; return true;
@ -1214,7 +1187,6 @@ check_target_abi(const char *target_abi)
return false; return false;
} }
static void static void
get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size) get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size)
{ {
@ -1229,22 +1201,19 @@ LLVMBool
WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
LLVMModuleRef M, LLVMModuleRef M,
struct LLVMMCJITCompilerOptions *Options, struct LLVMMCJITCompilerOptions *Options,
size_t SizeOfOptions, size_t SizeOfOptions, char **OutError);
char **OutError);
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM); void
LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
#if WASM_ENABLE_LAZY_JIT != 0 #if WASM_ENABLE_LAZY_JIT != 0
void void
aot_handle_llvm_errmsg(char *error_buf, aot_handle_llvm_errmsg(char *error_buf, uint32 error_buf_size,
uint32 error_buf_size, const char *string, LLVMErrorRef error)
const char *string,
LLVMErrorRef error)
{ {
char *err_msg = LLVMGetErrorMessage(error); char *err_msg = LLVMGetErrorMessage(error);
if (error_buf != NULL) { if (error_buf != NULL) {
snprintf(error_buf, error_buf_size, snprintf(error_buf, error_buf_size, "%s: %s", string, err_msg);
"%s: %s", string, err_msg);
} }
LLVMDisposeErrorMessage(err_msg); LLVMDisposeErrorMessage(err_msg);
} }
@ -1301,24 +1270,20 @@ llvm_orcjit_create(AOTCompContext *comp_ctx)
goto fail; goto fail;
} }
LOG_VERBOSE("LLVM ORCJIT detected CPU \"%s\", with features \"%s\"\n", LOG_VERBOSE("LLVM ORCJIT detected CPU \"%s\", with features \"%s\"\n", cpu,
cpu, features); features);
tm_opt = LLVMCreateTargetMachine(llvm_targetref, llvm_triple, tm_opt = LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
cpu, features,
LLVMCodeGenLevelAggressive, LLVMCodeGenLevelAggressive,
LLVMRelocDefault, LLVMRelocDefault, LLVMCodeModelJITDefault);
LLVMCodeModelJITDefault);
if (!tm_opt) { if (!tm_opt) {
snprintf(buf, sizeof(buf), "failed to create target machine."); snprintf(buf, sizeof(buf), "failed to create target machine.");
goto fail; goto fail;
} }
tm_opt2 = LLVMCreateTargetMachine(llvm_targetref, llvm_triple, tm_opt2 = LLVMCreateTargetMachine(
cpu, features, llvm_targetref, llvm_triple, cpu, features, LLVMCodeGenLevelAggressive,
LLVMCodeGenLevelAggressive, LLVMRelocDefault, LLVMCodeModelJITDefault);
LLVMRelocDefault,
LLVMCodeModelJITDefault);
if (!tm_opt2) { if (!tm_opt2) {
snprintf(buf, sizeof(buf), "failed to create target machine2."); snprintf(buf, sizeof(buf), "failed to create target machine2.");
goto fail; goto fail;
@ -1352,10 +1317,10 @@ llvm_orcjit_create(AOTCompContext *comp_ctx)
lazy_orcjit_builder = NULL; lazy_orcjit_builder = NULL;
error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
&main_gen, LLVMOrcLLLazyJITGetGlobalPrefix(lazy_orcjit), &main_gen, LLVMOrcLLLazyJITGetGlobalPrefix(lazy_orcjit), 0, NULL);
0, NULL);
if (error) { if (error) {
aot_handle_llvm_errmsg(buf, sizeof(buf), aot_handle_llvm_errmsg(
buf, sizeof(buf),
"failed to create dynmaic library search generator", error); "failed to create dynmaic library search generator", error);
goto fail; goto fail;
} }
@ -1394,8 +1359,7 @@ fail:
#endif /* WASM_ENABLE_LAZY_JIT != 0 */ #endif /* WASM_ENABLE_LAZY_JIT != 0 */
AOTCompContext * AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
aot_comp_option_t option)
{ {
AOTCompContext *comp_ctx, *ret = NULL; AOTCompContext *comp_ctx, *ret = NULL;
#if WASM_ENABLE_LAZY_JIT == 0 #if WASM_ENABLE_LAZY_JIT == 0
@ -1406,7 +1370,8 @@ aot_create_comp_context(AOTCompData *comp_data,
char *triple = NULL, *triple_norm, *arch, *abi; char *triple = NULL, *triple_norm, *arch, *abi;
char *cpu = NULL, *features, buf[128]; char *cpu = NULL, *features, buf[128];
char *triple_norm_new = NULL, *cpu_new = NULL; char *triple_norm_new = NULL, *cpu_new = NULL;
char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict"; char *err = NULL, *fp_round = "round.tonearest",
*fp_exce = "fpexcept.strict";
char triple_buf[32] = { 0 }, features_buf[128] = { 0 }; char triple_buf[32] = { 0 }, features_buf[128] = { 0 };
uint32 opt_level, size_level; uint32 opt_level, size_level;
LLVMCodeModel code_model; LLVMCodeModel code_model;
@ -1460,8 +1425,8 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail; goto fail;
} }
if (!(comp_ctx->module = if (!(comp_ctx->module = LLVMModuleCreateWithNameInContext(
LLVMModuleCreateWithNameInContext("WASM Module", comp_ctx->context))) { "WASM Module", comp_ctx->context))) {
aot_set_last_error("create LLVM module failed."); aot_set_last_error("create LLVM module failed.");
goto fail; goto fail;
} }
@ -1533,9 +1498,10 @@ aot_create_comp_context(AOTCompData *comp_data,
jit_options.OptLevel = LLVMCodeGenLevelAggressive; jit_options.OptLevel = LLVMCodeGenLevelAggressive;
jit_options.EnableFastISel = true; jit_options.EnableFastISel = true;
/*jit_options.CodeModel = LLVMCodeModelSmall;*/ /*jit_options.CodeModel = LLVMCodeModelSmall;*/
if (WAMRCreateMCJITCompilerForModule if (WAMRCreateMCJITCompilerForModule(&comp_ctx->exec_engine,
(&comp_ctx->exec_engine, comp_ctx->module, comp_ctx->module, &jit_options,
&jit_options, sizeof(jit_options), &err) != 0) { sizeof(jit_options), &err)
!= 0) {
if (err) { if (err) {
LLVMDisposeMessage(err); LLVMDisposeMessage(err);
err = NULL; err = NULL;
@ -1555,8 +1521,8 @@ aot_create_comp_context(AOTCompData *comp_data,
#endif #endif
#if WASM_ENABLE_LAZY_JIT != 0 #if WASM_ENABLE_LAZY_JIT != 0
if (!(triple_jit = if (!(triple_jit = (char *)LLVMOrcLLLazyJITGetTripleString(
(char *)LLVMOrcLLLazyJITGetTripleString(comp_ctx->lazy_orcjit))) { comp_ctx->lazy_orcjit))) {
aot_set_last_error("can not get triple from the target machine"); aot_set_last_error("can not get triple from the target machine");
goto fail; goto fail;
} }
@ -1607,7 +1573,8 @@ aot_create_comp_context(AOTCompData *comp_data,
if (!strcmp(arch, "help")) if (!strcmp(arch, "help"))
print_supported_targets(); print_supported_targets();
else else
aot_set_last_error("Invalid target. " aot_set_last_error(
"Invalid target. "
"Use --target=help to list all supported targets"); "Use --target=help to list all supported targets");
goto fail; goto fail;
} }
@ -1617,7 +1584,8 @@ aot_create_comp_context(AOTCompData *comp_data,
if (!strcmp(abi, "help")) if (!strcmp(abi, "help"))
print_supported_abis(); print_supported_abis();
else else
aot_set_last_error("Invalid target ABI. " aot_set_last_error(
"Invalid target ABI. "
"Use --target-abi=help to list all supported ABI"); "Use --target-abi=help to list all supported ABI");
goto fail; goto fail;
} }
@ -1658,10 +1626,12 @@ aot_create_comp_context(AOTCompData *comp_data,
LLVMDisposeMessage(default_triple); LLVMDisposeMessage(default_triple);
bh_assert(strlen(arch) + strlen(vendor_sys) + strlen(abi) < sizeof(triple_buf)); bh_assert(strlen(arch) + strlen(vendor_sys) + strlen(abi)
< sizeof(triple_buf));
memcpy(triple_buf, arch, strlen(arch)); memcpy(triple_buf, arch, strlen(arch));
memcpy(triple_buf + strlen(arch), vendor_sys, strlen(vendor_sys)); memcpy(triple_buf + strlen(arch), vendor_sys, strlen(vendor_sys));
memcpy(triple_buf + strlen(arch) + strlen(vendor_sys), abi, strlen(abi)); memcpy(triple_buf + strlen(arch) + strlen(vendor_sys), abi,
strlen(abi));
triple = triple_buf; triple = triple_buf;
} }
@ -1672,7 +1642,8 @@ aot_create_comp_context(AOTCompData *comp_data,
if (!triple && !cpu) { if (!triple && !cpu) {
/* Get a triple for the host machine */ /* Get a triple for the host machine */
if (!(triple_norm = triple_norm_new = LLVMGetDefaultTargetTriple())) { if (!(triple_norm = triple_norm_new =
LLVMGetDefaultTargetTriple())) {
aot_set_last_error("llvm get default target triple failed."); aot_set_last_error("llvm get default target triple failed.");
goto fail; goto fail;
} }
@ -1684,7 +1655,8 @@ aot_create_comp_context(AOTCompData *comp_data,
} }
else if (triple) { else if (triple) {
/* Normalize a target triple */ /* Normalize a target triple */
if (!(triple_norm = triple_norm_new = LLVMNormalizeTargetTriple(triple))) { if (!(triple_norm = triple_norm_new =
LLVMNormalizeTargetTriple(triple))) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"llvm normlalize target triple (%s) failed.", triple); "llvm normlalize target triple (%s) failed.", triple);
aot_set_last_error(buf); aot_set_last_error(buf);
@ -1695,8 +1667,8 @@ aot_create_comp_context(AOTCompData *comp_data,
} }
else { else {
/* triple is NULL, cpu isn't NULL */ /* triple is NULL, cpu isn't NULL */
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf), "target isn't specified for cpu %s.",
"target isn't specified for cpu %s.", cpu); cpu);
aot_set_last_error(buf); aot_set_last_error(buf);
goto fail; goto fail;
} }
@ -1711,12 +1683,13 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail; goto fail;
} }
LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorError, LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorError,
"target-abi", strlen("target-abi"), meta_target_abi); "target-abi", strlen("target-abi"),
meta_target_abi);
if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) { if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
if (features) { if (features) {
snprintf(features_buf, sizeof(features_buf), snprintf(features_buf, sizeof(features_buf), "%s%s",
"%s%s", features, ",+d"); features, ",+d");
features = features_buf; features = features_buf;
} }
else else
@ -1751,7 +1724,8 @@ aot_create_comp_context(AOTCompData *comp_data,
} }
else { else {
/* Unset by user, use default value */ /* Unset by user, use default value */
if (strstr(comp_ctx->target_arch, "64") && !option->is_sgx_platform) { if (strstr(comp_ctx->target_arch, "64")
&& !option->is_sgx_platform) {
comp_ctx->enable_bound_check = false; comp_ctx->enable_bound_check = false;
} }
else { else {
@ -1788,13 +1762,14 @@ aot_create_comp_context(AOTCompData *comp_data,
} }
/* Report error if target isn't arc and hasn't asm backend. /* Report error if target isn't arc and hasn't asm backend.
For arc target, as it cannot emit to memory buffer of elf file currently, For arc target, as it cannot emit to memory buffer of elf file
we let it emit to assembly file instead, and then call arc-gcc to compile currently, we let it emit to assembly file instead, and then call
arc-gcc to compile
asm file to elf file, and read elf file to memory buffer. */ asm file to elf file, and read elf file to memory buffer. */
if (strncmp(comp_ctx->target_arch, "arc", 3) if (strncmp(comp_ctx->target_arch, "arc", 3)
&& !LLVMTargetHasAsmBackend(target)) { && !LLVMTargetHasAsmBackend(target)) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf), "no asm backend for this target (%s).",
"no asm backend for this target (%s).", LLVMGetTargetName(target)); LLVMGetTargetName(target));
aot_set_last_error(buf); aot_set_last_error(buf);
goto fail; goto fail;
} }
@ -1810,17 +1785,15 @@ aot_create_comp_context(AOTCompData *comp_data,
code_model = LLVMCodeModelSmall; code_model = LLVMCodeModelSmall;
/* Create the target machine */ /* Create the target machine */
if (!(comp_ctx->target_machine = if (!(comp_ctx->target_machine = LLVMCreateTargetMachine(
LLVMCreateTargetMachine(target, triple_norm, cpu, features, target, triple_norm, cpu, features, opt_level,
opt_level, LLVMRelocStatic, LLVMRelocStatic, code_model))) {
code_model))) {
aot_set_last_error("create LLVM target machine failed."); aot_set_last_error("create LLVM target machine failed.");
goto fail; goto fail;
} }
} }
if (option->enable_simd if (option->enable_simd && strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strncmp(comp_ctx->target_arch, "aarch64", 7) != 0) { && strncmp(comp_ctx->target_arch, "aarch64", 7) != 0) {
/* Disable simd if it isn't supported by target arch */ /* Disable simd if it isn't supported by target arch */
option->enable_simd = false; option->enable_simd = false;
@ -1859,8 +1832,8 @@ aot_create_comp_context(AOTCompData *comp_data,
if (option->output_format == AOT_LLVMIR_UNOPT_FILE) if (option->output_format == AOT_LLVMIR_UNOPT_FILE)
comp_ctx->optimize = false; comp_ctx->optimize = false;
if (!(comp_ctx->pass_mgr = LLVMCreateFunctionPassManagerForModule if (!(comp_ctx->pass_mgr =
(comp_ctx->module))) { LLVMCreateFunctionPassManagerForModule(comp_ctx->module))) {
aot_set_last_error("create LLVM pass manager failed."); aot_set_last_error("create LLVM pass manager failed.");
goto fail; goto fail;
} }
@ -1892,14 +1865,10 @@ aot_create_comp_context(AOTCompData *comp_data,
} }
/* Create metadata for llvm float experimental constrained intrinsics */ /* Create metadata for llvm float experimental constrained intrinsics */
if (!(comp_ctx->fp_rounding_mode = if (!(comp_ctx->fp_rounding_mode = LLVMMDStringInContext(
LLVMMDStringInContext(comp_ctx->context, comp_ctx->context, fp_round, (uint32)strlen(fp_round)))
fp_round, || !(comp_ctx->fp_exception_behavior = LLVMMDStringInContext(
(uint32)strlen(fp_round))) comp_ctx->context, fp_exce, (uint32)strlen(fp_exce)))) {
|| !(comp_ctx->fp_exception_behavior =
LLVMMDStringInContext(comp_ctx->context,
fp_exce,
(uint32)strlen(fp_exce)))) {
aot_set_last_error("create float llvm metadata failed."); aot_set_last_error("create float llvm metadata failed.");
goto fail; goto fail;
} }
@ -2167,8 +2136,8 @@ aot_block_destroy(AOTBlock *block)
} }
bool bool
aot_checked_addr_list_add(AOTFuncContext *func_ctx, aot_checked_addr_list_add(AOTFuncContext *func_ctx, uint32 local_idx,
uint32 local_idx, uint32 offset, uint32 bytes) uint32 offset, uint32 bytes)
{ {
AOTCheckedAddr *node = func_ctx->checked_addr_list; AOTCheckedAddr *node = func_ctx->checked_addr_list;
@ -2211,14 +2180,13 @@ aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx)
} }
bool bool
aot_checked_addr_list_find(AOTFuncContext *func_ctx, aot_checked_addr_list_find(AOTFuncContext *func_ctx, uint32 local_idx,
uint32 local_idx, uint32 offset, uint32 bytes) uint32 offset, uint32 bytes)
{ {
AOTCheckedAddr *node = func_ctx->checked_addr_list; AOTCheckedAddr *node = func_ctx->checked_addr_list;
while (node) { while (node) {
if (node->local_idx == local_idx if (node->local_idx == local_idx && node->offset == offset
&& node->offset == offset
&& node->bytes >= bytes) { && node->bytes >= bytes) {
return true; return true;
} }
@ -2243,8 +2211,7 @@ aot_checked_addr_list_destroy(AOTFuncContext *func_ctx)
} }
bool bool
aot_build_zero_function_ret(AOTCompContext *comp_ctx, aot_build_zero_function_ret(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
AOTFuncType *func_type) AOTFuncType *func_type)
{ {
LLVMValueRef ret = NULL; LLVMValueRef ret = NULL;
@ -2284,7 +2251,8 @@ aot_build_zero_function_ret(AOTCompContext *comp_ctx,
return false; return false;
} }
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
LLVMMetadataRef return_location = dwarf_gen_func_ret_location(comp_ctx, func_ctx); LLVMMetadataRef return_location =
dwarf_gen_func_ret_location(comp_ctx, func_ctx);
LLVMInstructionSetDebugLoc(ret, return_location); LLVMInstructionSetDebugLoc(ret, return_location);
#endif #endif
return true; return true;
@ -2292,12 +2260,9 @@ aot_build_zero_function_ret(AOTCompContext *comp_ctx,
static LLVMValueRef static LLVMValueRef
__call_llvm_intrinsic(const AOTCompContext *comp_ctx, __call_llvm_intrinsic(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, const char *name,
const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
LLVMTypeRef ret_type, int param_count, LLVMValueRef *param_values)
LLVMTypeRef *param_types,
int param_count,
LLVMValueRef *param_values)
{ {
LLVMValueRef func, ret; LLVMValueRef func, ret;
LLVMTypeRef func_type; LLVMTypeRef func_type;
@ -2347,7 +2312,8 @@ __call_llvm_intrinsic(const AOTCompContext *comp_ctx,
if (!(func = LLVMGetNamedFunction(comp_ctx->module, name))) { if (!(func = LLVMGetNamedFunction(comp_ctx->module, name))) {
if (!(func_type = LLVMFunctionType(ret_type, param_types, if (!(func_type = LLVMFunctionType(ret_type, param_types,
(uint32)param_count, false))) { (uint32)param_count, false))) {
aot_set_last_error("create LLVM intrinsic function type failed."); aot_set_last_error(
"create LLVM intrinsic function type failed.");
return NULL; return NULL;
} }
@ -2370,12 +2336,9 @@ __call_llvm_intrinsic(const AOTCompContext *comp_ctx,
LLVMValueRef LLVMValueRef
aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx, aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, const char *intrinsic,
const char *intrinsic, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
LLVMTypeRef ret_type, int param_count, ...)
LLVMTypeRef *param_types,
int param_count,
...)
{ {
LLVMValueRef *param_values, ret; LLVMValueRef *param_values, ret;
va_list argptr; va_list argptr;
@ -2406,12 +2369,9 @@ aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
LLVMValueRef LLVMValueRef
aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx, aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, const char *intrinsic,
const char *intrinsic, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
LLVMTypeRef ret_type, int param_count, va_list param_value_list)
LLVMTypeRef *param_types,
int param_count,
va_list param_value_list)
{ {
LLVMValueRef *param_values, ret; LLVMValueRef *param_values, ret;
uint64 total_size; uint64 total_size;
@ -2462,8 +2422,8 @@ aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
goto fail; goto fail;
} }
if (!(func = LLVMBuildBitCast(comp_ctx->builder, func, func_type, if (!(func =
"func"))) { LLVMBuildBitCast(comp_ctx->builder, func, func_type, "func"))) {
aot_set_last_error("cast function fialed."); aot_set_last_error("cast function fialed.");
goto fail; goto fail;
} }

View File

@ -33,7 +33,6 @@
extern "C" { extern "C" {
#endif #endif
/** /**
* Value in the WASM operation stack, each stack element * Value in the WASM operation stack, each stack element
* is an LLVM value * is an LLVM value
@ -360,8 +359,7 @@ typedef struct AOTCompOption{
} AOTCompOption, *aot_comp_option_t; } AOTCompOption, *aot_comp_option_t;
AOTCompContext * AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
aot_comp_option_t option);
void void
aot_destroy_comp_context(AOTCompContext *comp_ctx); aot_destroy_comp_context(AOTCompContext *comp_ctx);
@ -403,57 +401,46 @@ LLVMTypeRef
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type); wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
bool bool
aot_checked_addr_list_add(AOTFuncContext *func_ctx, aot_checked_addr_list_add(AOTFuncContext *func_ctx, uint32 local_idx,
uint32 local_idx, uint32 offset, uint32 bytes); uint32 offset, uint32 bytes);
void void
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx); aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
bool bool
aot_checked_addr_list_find(AOTFuncContext *func_ctx, aot_checked_addr_list_find(AOTFuncContext *func_ctx, uint32 local_idx,
uint32 local_idx, uint32 offset, uint32 bytes); uint32 offset, uint32 bytes);
void void
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx); aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
bool bool
aot_build_zero_function_ret(AOTCompContext *comp_ctx, aot_build_zero_function_ret(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
AOTFuncType *func_type); AOTFuncType *func_type);
LLVMValueRef LLVMValueRef
aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx, aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, const char *intrinsic,
const char *intrinsic, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
LLVMTypeRef ret_type, int param_count, ...);
LLVMTypeRef *param_types,
int param_count,
...);
LLVMValueRef LLVMValueRef
aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx, aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, const char *intrinsic,
const char *intrinsic, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
LLVMTypeRef ret_type, int param_count, va_list param_value_list);
LLVMTypeRef *param_types,
int param_count,
va_list param_value_list);
LLVMValueRef LLVMValueRef
aot_get_func_from_table(const AOTCompContext *comp_ctx, aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
LLVMValueRef base, LLVMTypeRef func_type, int32 index);
LLVMTypeRef func_type,
int32 index);
bool bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str); aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
#if WASM_ENABLE_LAZY_JIT != 0 #if WASM_ENABLE_LAZY_JIT != 0
void void
aot_handle_llvm_errmsg(char *error_buf, aot_handle_llvm_errmsg(char *error_buf, uint32 error_buf_size,
uint32 error_buf_size, const char *string, LLVMErrorRef error);
const char *string,
LLVMErrorRef error);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -461,4 +448,3 @@ aot_handle_llvm_errmsg(char *error_buf,
#endif #endif
#endif /* end of _AOT_LLVM_H_ */ #endif /* end of _AOT_LLVM_H_ */

View File

@ -28,8 +28,7 @@ extern "C" LLVMBool
WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
LLVMModuleRef M, LLVMModuleRef M,
LLVMMCJITCompilerOptions *PassedOptions, LLVMMCJITCompilerOptions *PassedOptions,
size_t SizeOfPassedOptions, size_t SizeOfPassedOptions, char **OutError);
char **OutError);
extern "C" bool extern "C" bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str); aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
@ -38,23 +37,21 @@ LLVMBool
WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
LLVMModuleRef M, LLVMModuleRef M,
LLVMMCJITCompilerOptions *PassedOptions, LLVMMCJITCompilerOptions *PassedOptions,
size_t SizeOfPassedOptions, size_t SizeOfPassedOptions, char **OutError)
char **OutError)
{ {
LLVMMCJITCompilerOptions options; LLVMMCJITCompilerOptions options;
// If the user passed a larger sized options struct, then they were compiled // If the user passed a larger sized options struct, then they were compiled
// against a newer LLVM. Tell them that something is wrong. // against a newer LLVM. Tell them that something is wrong.
if (SizeOfPassedOptions > sizeof(options)) { if (SizeOfPassedOptions > sizeof(options)) {
*OutError = strdup( *OutError = strdup("Refusing to use options struct that is larger than "
"Refusing to use options struct that is larger than my own; assuming " "my own; assuming LLVM library mismatch.");
"LLVM library mismatch.");
return 1; return 1;
} }
// Defend against the user having an old version of the API by ensuring that // Defend against the user having an old version of the API by ensuring that
// any fields they didn't see are cleared. We must defend against fields being // any fields they didn't see are cleared. We must defend against fields
// set to the bitwise equivalent of zero, and assume that this means "do the // being set to the bitwise equivalent of zero, and assume that this means
// default" as if that option hadn't been available. // "do the default" as if that option hadn't been available.
LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
memcpy(&options, PassedOptions, SizeOfPassedOptions); memcpy(&options, PassedOptions, SizeOfPassedOptions);
@ -68,7 +65,8 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
for (auto &F : *Mod) { for (auto &F : *Mod) {
auto Attrs = F.getAttributes(); auto Attrs = F.getAttributes();
StringRef Value = options.NoFramePointerElim ? "all" : "none"; StringRef Value = options.NoFramePointerElim ? "all" : "none";
Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex, Attrs =
Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
"frame-pointer", Value); "frame-pointer", Value);
F.setAttributes(Attrs); F.setAttributes(Attrs);
} }
@ -145,4 +143,3 @@ aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
return true; return true;
#endif /* WASM_ENABLE_SIMD */ #endif /* WASM_ENABLE_SIMD */
} }

View File

@ -15,8 +15,7 @@ void
LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder); LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
LLVMErrorRef LLVMErrorRef
LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, LLVMOrcLLJITBuilderRef Builder);
LLVMOrcLLJITBuilderRef Builder);
LLVMErrorRef LLVMErrorRef
LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J); LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
@ -31,13 +30,11 @@ char
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J); LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
LLVMErrorRef LLVMErrorRef
LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM); LLVMOrcThreadSafeModuleRef TSM);
LLVMErrorRef LLVMErrorRef
LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, LLVMOrcJITTargetAddress *Result,
LLVMOrcJITTargetAddress *Result,
const char *Name); const char *Name);
const char * const char *
@ -45,8 +42,7 @@ LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
void void
LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLJITBuilderRef Builder, LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
LLVMOrcJITTargetMachineBuilderRef JTMB);
char char
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J); LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
@ -91,16 +87,14 @@ LLVMOrcDisposeLLLazyJIT(LLVMOrcLLLazyJITRef J)
} }
LLVMErrorRef LLVMErrorRef
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcJITDylibRef JD,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM) LLVMOrcThreadSafeModuleRef TSM)
{ {
return LLVMOrcLLJITAddLLVMIRModule(J, JD, TSM); return LLVMOrcLLJITAddLLVMIRModule(J, JD, TSM);
} }
LLVMErrorRef LLVMErrorRef
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcJITTargetAddress *Result,
LLVMOrcJITTargetAddress *Result,
const char *Name) const char *Name)
{ {
return LLVMOrcLLJITLookup(J, Result, Name); return LLVMOrcLLJITLookup(J, Result, Name);
@ -114,8 +108,7 @@ LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J)
void void
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder( LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB)
LLVMOrcJITTargetMachineBuilderRef JTMB)
{ {
return LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB); return LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);
} }
@ -125,4 +118,3 @@ LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J)
{ {
return LLVMOrcLLJITGetGlobalPrefix(J); return LLVMOrcLLJITGetGlobalPrefix(J);
} }

View File

@ -14,7 +14,6 @@
#include "llvm-c/LLJIT.h" #include "llvm-c/LLJIT.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -49,13 +48,11 @@ char
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J); LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
LLVMErrorRef LLVMErrorRef
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcJITDylibRef JD,
LLVMOrcJITDylibRef JD,
LLVMOrcThreadSafeModuleRef TSM); LLVMOrcThreadSafeModuleRef TSM);
LLVMErrorRef LLVMErrorRef
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcJITTargetAddress *Result,
LLVMOrcJITTargetAddress *Result,
const char *Name); const char *Name);
const char * const char *
@ -63,8 +60,7 @@ LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J);
void void
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder( LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
LLVMOrcJITTargetMachineBuilderRef JTMB);
char char
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J); LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
@ -74,4 +70,3 @@ LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
#endif #endif
#endif /* end of AOT_LLVM_LAZYJIT_H */ #endif /* end of AOT_LLVM_LAZYJIT_H */

View File

@ -28,8 +28,7 @@
using namespace lldb; using namespace lldb;
typedef struct dwar_extractor typedef struct dwar_extractor {
{
SBDebugger debugger; SBDebugger debugger;
SBTarget target; SBTarget target;
SBModule module; SBModule module;
@ -129,8 +128,7 @@ dwarf_gen_file_info(AOTCompContext *comp_ctx)
units_number = extractor->module.GetNumCompileUnits(); units_number = extractor->module.GetNumCompileUnits();
if (units_number > 0) { if (units_number > 0) {
SBCompileUnit compile_unit = SBCompileUnit compile_unit = extractor->module.GetCompileUnitAtIndex(0);
extractor->module.GetCompileUnitAtIndex(0);
auto filespec = compile_unit.GetFileSpec(); auto filespec = compile_unit.GetFileSpec();
file_name = filespec.GetFilename(); file_name = filespec.GetFilename();
dir_name = filespec.GetDirectory(); dir_name = filespec.GetDirectory();
@ -205,8 +203,7 @@ dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx)
units_number = extractor->module.GetNumCompileUnits(); units_number = extractor->module.GetNumCompileUnits();
if (units_number > 0) { if (units_number > 0) {
SBCompileUnit compile_unit = SBCompileUnit compile_unit = extractor->module.GetCompileUnitAtIndex(0);
extractor->module.GetCompileUnitAtIndex(0);
auto lang_type = compile_unit.GetLanguage(); auto lang_type = compile_unit.GetLanguage();
comp_unit = LLVMDIBuilderCreateCompileUnit( comp_unit = LLVMDIBuilderCreateCompileUnit(
@ -217,18 +214,15 @@ dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx)
return comp_unit; return comp_unit;
} }
bool bool
dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset) dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset)
{ {
dwar_extractor *extractor = TO_EXTACTOR(handle); dwar_extractor *extractor = TO_EXTACTOR(handle);
auto sbaddr = extractor->target.ResolveFileAddress(offset); auto sbaddr = extractor->target.ResolveFileAddress(offset);
SBSymbolContext sc( SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction));
sbaddr.GetSymbolContext(eSymbolContextFunction));
if (sc.IsValid()) { if (sc.IsValid()) {
SBFunction function(sc.GetFunction()); SBFunction function(sc.GetFunction());
if (function.IsValid()) { if (function.IsValid()) {
} }
} }
} }
@ -237,8 +231,7 @@ static LLVMDWARFTypeEncoding
lldb_get_basic_type_encoding(BasicType basic_type) lldb_get_basic_type_encoding(BasicType basic_type)
{ {
LLVMDWARFTypeEncoding encoding = 0; LLVMDWARFTypeEncoding encoding = 0;
switch (basic_type) switch (basic_type) {
{
case eBasicTypeUnsignedChar: case eBasicTypeUnsignedChar:
encoding = llvm::dwarf::DW_ATE_unsigned_char; encoding = llvm::dwarf::DW_ATE_unsigned_char;
break; break;
@ -302,7 +295,8 @@ lldb_type_to_type_dbi(AOTCompContext *comp_ctx, SBType &type)
} }
static LLVMMetadataRef static LLVMMetadataRef
lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc, AOTFuncContext *func_ctx) lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc,
AOTFuncContext *func_ctx)
{ {
SBFunction function(sc.GetFunction()); SBFunction function(sc.GetFunction());
const char *function_name = function.GetName(); const char *function_name = function.GetName();
@ -315,13 +309,11 @@ lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc, AOT
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
return NULL; return NULL;
LLVMDIBuilderRef DIB = comp_ctx->debug_builder; LLVMDIBuilderRef DIB = comp_ctx->debug_builder;
LLVMMetadataRef File = comp_ctx->debug_file; LLVMMetadataRef File = comp_ctx->debug_file;
LLVMMetadataRef ParamTypes[num_function_args + 1]; LLVMMetadataRef ParamTypes[num_function_args + 1];
ParamTypes[0] = lldb_type_to_type_dbi(comp_ctx, return_type); ParamTypes[0] = lldb_type_to_type_dbi(comp_ctx, return_type);
for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args;
@ -330,12 +322,13 @@ lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc, AOT
function_args.GetTypeAtIndex(function_arg_idx); function_args.GetTypeAtIndex(function_arg_idx);
if (function_arg_type.IsValid()) { if (function_arg_type.IsValid()) {
ParamTypes[function_arg_idx + 1] = lldb_type_to_type_dbi(comp_ctx, function_arg_type); ParamTypes[function_arg_idx + 1] =
lldb_type_to_type_dbi(comp_ctx, function_arg_type);
} }
} }
LLVMMetadataRef FunctionTy = LLVMMetadataRef FunctionTy = LLVMDIBuilderCreateSubroutineType(
LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, num_function_args + 1, LLVMDIFlagZero); DIB, File, ParamTypes, num_function_args + 1, LLVMDIFlagZero);
auto line_entry = sc.GetLineEntry(); auto line_entry = sc.GetLineEntry();
LLVMMetadataRef ReplaceableFunctionMetadata = LLVMMetadataRef ReplaceableFunctionMetadata =
@ -343,44 +336,46 @@ lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc, AOT
DIB, 0x15, function_name, strlen(function_name), File, File, DIB, 0x15, function_name, strlen(function_name), File, File,
line_entry.GetLine(), 0, 0, 0, LLVMDIFlagFwdDecl, "", 0); line_entry.GetLine(), 0, 0, 0, LLVMDIFlagFwdDecl, "", 0);
LLVMMetadataRef FunctionMetadata = LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction(
LLVMDIBuilderCreateFunction(DIB, File, function_name, strlen(function_name), link_name, strlen(link_name), DIB, File, function_name, strlen(function_name), link_name,
File, line_entry.GetLine(), FunctionTy, true, true, line_entry.GetLine(), LLVMDIFlagZero, false); strlen(link_name), File, line_entry.GetLine(), FunctionTy, true, true,
line_entry.GetLine(), LLVMDIFlagZero, false);
LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata); LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata,
FunctionMetadata);
LLVMSetSubprogram(func_ctx->func, FunctionMetadata); LLVMSetSubprogram(func_ctx->func, FunctionMetadata);
LLVMMetadataRef ParamExpression = LLVMDIBuilderCreateExpression(DIB, NULL, 0); LLVMMetadataRef ParamExpression =
auto variable_list = function.GetBlock().GetVariables(extractor->target, true, false,false); LLVMDIBuilderCreateExpression(DIB, NULL, 0);
if (num_function_args != variable_list.GetSize()) auto variable_list =
{ function.GetBlock().GetVariables(extractor->target, true, false, false);
LOG_ERROR("function args number dismatch!:value number=%d, function args=%d", variable_list.GetSize(), num_function_args); if (num_function_args != variable_list.GetSize()) {
LOG_ERROR(
"function args number dismatch!:value number=%d, function args=%d",
variable_list.GetSize(), num_function_args);
} }
LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation( LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
comp_ctx->context, line_entry.GetLine(), 0, FunctionMetadata, NULL); comp_ctx->context, line_entry.GetLine(), 0, FunctionMetadata, NULL);
// TODO:change to void * or WasmExenv * // TODO:change to void * or WasmExenv *
LLVMMetadataRef voidtype = LLVMDIBuilderCreateBasicType(DIB, "void", 4, 0, 0, LLVMDIFlagZero); LLVMMetadataRef voidtype =
LLVMMetadataRef voidpionter = LLVMDIBuilderCreatePointerType(DIB, voidtype, 64, 0, 0, "void *", 6); LLVMDIBuilderCreateBasicType(DIB, "void", 4, 0, 0, LLVMDIFlagZero);
LLVMMetadataRef voidpionter =
LLVMDIBuilderCreatePointerType(DIB, voidtype, 64, 0, 0, "void *", 6);
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable( LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
DIB, FunctionMetadata, "exenv", DIB, FunctionMetadata, "exenv", 5, 1,
5, 1,
File, // starts form 1, and 1 is exenv, File, // starts form 1, and 1 is exenv,
line_entry.GetLine(), voidpionter, true, line_entry.GetLine(), voidpionter, true, LLVMDIFlagZero);
LLVMDIFlagZero); LLVMValueRef Param = LLVMGetParam(func_ctx->func, 0);
LLVMValueRef Param = LLVMBasicBlockRef block_curr = LLVMGetEntryBasicBlock(func_ctx->func);
LLVMGetParam(func_ctx->func, 0); LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar, ParamExpression,
LLVMBasicBlockRef block_curr = ParamLocation, block_curr);
LLVMGetEntryBasicBlock(func_ctx->func);
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar,
ParamExpression, ParamLocation,
block_curr);
for (uint32_t function_arg_idx = 0; function_arg_idx < variable_list.GetSize(); for (uint32_t function_arg_idx = 0;
++function_arg_idx) { function_arg_idx < variable_list.GetSize(); ++function_arg_idx) {
SBValue variable(variable_list.GetValueAtIndex(function_arg_idx)); SBValue variable(variable_list.GetValueAtIndex(function_arg_idx));
if (variable.IsValid()) { if (variable.IsValid()) {
SBDeclaration dec(variable.GetDeclaration()); SBDeclaration dec(variable.GetDeclaration());
@ -413,7 +408,6 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
uint64_t vm_offset; uint64_t vm_offset;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
return NULL; return NULL;
@ -424,8 +418,8 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
vm_offset = func->code - comp_ctx->comp_data->wasm_module->buf_code; vm_offset = func->code - comp_ctx->comp_data->wasm_module->buf_code;
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset); auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
SBSymbolContext sc( SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction
sbaddr.GetSymbolContext(eSymbolContextFunction | eSymbolContextLineEntry)); | eSymbolContextLineEntry));
if (sc.IsValid()) { if (sc.IsValid()) {
SBFunction function(sc.GetFunction()); SBFunction function(sc.GetFunction());
if (function.IsValid()) { if (function.IsValid()) {
@ -436,10 +430,8 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
void void
dwarf_get_func_name(AOTCompContext *comp_ctx, dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, char *name, int len)
char *name,
int len)
{ {
LLVMMetadataRef func_info = NULL; LLVMMetadataRef func_info = NULL;
dwar_extractor *extractor; dwar_extractor *extractor;
@ -469,8 +461,7 @@ dwarf_get_func_name(AOTCompContext *comp_ctx,
} }
LLVMMetadataRef LLVMMetadataRef
dwarf_gen_location(AOTCompContext *comp_ctx, dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint64_t vm_offset) uint64_t vm_offset)
{ {
LLVMMetadataRef location_info = NULL; LLVMMetadataRef location_info = NULL;
@ -495,12 +486,13 @@ dwarf_gen_location(AOTCompContext *comp_ctx,
if (function.GetStartAddress().GetOffset() <= start if (function.GetStartAddress().GetOffset() <= start
&& end <= function.GetEndAddress().GetOffset()) { && end <= function.GetEndAddress().GetOffset()) {
auto line_entry = sc.GetLineEntry(); auto line_entry = sc.GetLineEntry();
location_info = location_info = LLVMDIBuilderCreateDebugLocation(
LLVMDIBuilderCreateDebugLocation(
comp_ctx->context, line_entry.GetLine(), comp_ctx->context, line_entry.GetLine(),
line_entry.GetColumn(), func_ctx->debug_func, NULL); line_entry.GetColumn(), func_ctx->debug_func, NULL);
//LOG_VERBOSE("Gen the location l:%d, c:%d at %lx", line_entry.GetLine(), line_entry.GetColumn(), vm_offset); // LOG_VERBOSE("Gen the location l:%d, c:%d at %lx",
} else // line_entry.GetLine(), line_entry.GetColumn(), vm_offset);
}
else
LOG_WARNING("the offset and function is not matched"); LOG_WARNING("the offset and function is not matched");
} }
} }
@ -523,7 +515,8 @@ dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
// instruction relative within the Code section of the WebAssembly file. // instruction relative within the Code section of the WebAssembly file.
// For this reason Section::GetFileAddress() must return zero for the // For this reason Section::GetFileAddress() must return zero for the
// Code section. (refert to ObjectFileWasm.cpp) // Code section. (refert to ObjectFileWasm.cpp)
vm_offset = (func->code + func->code_size -1) - comp_ctx->comp_data->wasm_module->buf_code; vm_offset = (func->code + func->code_size - 1)
- comp_ctx->comp_data->wasm_module->buf_code;
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset); location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset);
return location_info; return location_info;

View File

@ -11,6 +11,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef unsigned int LLDBLangType; typedef unsigned int LLDBLangType;
#define LLDB_TO_LLVM_LANG_TYPE(lldb_lang_type) \ #define LLDB_TO_LLVM_LANG_TYPE(lldb_lang_type) \
(LLVMDWARFSourceLanguage)(((lldb_lang_type) > 0 ? (lldb_lang_type)-1 : 1)) (LLVMDWARFSourceLanguage)(((lldb_lang_type) > 0 ? (lldb_lang_type)-1 : 1))
@ -38,19 +39,16 @@ LLVMMetadataRef
dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
LLVMMetadataRef LLVMMetadataRef
dwarf_gen_location(AOTCompContext *comp_ctx, dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint64_t vm_offset); uint64_t vm_offset);
LLVMMetadataRef LLVMMetadataRef
dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
AOTFuncContext *func_ctx);
void void
dwarf_get_func_name(AOTCompContext *comp_ctx, dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, char *name, int len);
char *name,
int len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -9,8 +9,7 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
bool bool
aot_compile_simd_shuffle(AOTCompContext *comp_ctx, aot_compile_simd_shuffle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
const uint8 *frame_ip) const uint8 *frame_ip)
{ {
LLVMValueRef vec1, vec2, mask, result; LLVMValueRef vec1, vec2, mask, result;
@ -34,8 +33,8 @@ aot_compile_simd_shuffle(AOTCompContext *comp_ctx,
} }
/* build a vector <16 x i32> */ /* build a vector <16 x i32> */
if (!(mask = if (!(mask = simd_build_const_integer_vector(comp_ctx, I32_TYPE, values,
simd_build_const_integer_vector(comp_ctx, I32_TYPE, values, 16))) { 16))) {
goto fail; goto fail;
} }
@ -54,8 +53,7 @@ fail:
/*TODO: llvm.experimental.vector.*/ /*TODO: llvm.experimental.vector.*/
/* shufflevector is not an option, since it requires *mask as a const */ /* shufflevector is not an option, since it requires *mask as a const */
bool bool
aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx, aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
LLVMValueRef vector, mask, max_lanes, condition, mask_lanes, result; LLVMValueRef vector, mask, max_lanes, condition, mask_lanes, result;
LLVMTypeRef param_types[2]; LLVMTypeRef param_types[2];
@ -71,13 +69,15 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
} }
/* icmp uge <16 x i8> mask, <16, 16, 16, 16, ...> */ /* icmp uge <16 x i8> mask, <16, 16, 16, 16, ...> */
if (!(max_lanes = simd_build_splat_const_integer_vector( if (!(max_lanes = simd_build_splat_const_integer_vector(comp_ctx, INT8_TYPE,
comp_ctx, INT8_TYPE, 16, 16))) { 16, 16))) {
goto fail; goto fail;
} }
/* if the highest bit of every i8 of mask is 1, means doesn't pick up from vector */ /* if the highest bit of every i8 of mask is 1, means doesn't pick up
/* select <16 x i1> %condition, <16 x i8> <0x80, 0x80, ...>, <16 x i8> %mask */ from vector */
/* select <16 x i1> %condition, <16 x i8> <0x80, 0x80, ...>,
<16 x i8> %mask */
if (!(mask_lanes = simd_build_splat_const_integer_vector( if (!(mask_lanes = simd_build_splat_const_integer_vector(
comp_ctx, INT8_TYPE, 0x80, 16))) { comp_ctx, INT8_TYPE, 0x80, 16))) {
goto fail; goto fail;
@ -89,8 +89,8 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
goto fail; goto fail;
} }
if (!(mask = LLVMBuildSelect(comp_ctx->builder, condition, mask_lanes, if (!(mask = LLVMBuildSelect(comp_ctx->builder, condition, mask_lanes, mask,
mask, "mask"))) { "mask"))) {
HANDLE_FAILURE("LLVMBuildSelect"); HANDLE_FAILURE("LLVMBuildSelect");
goto fail; goto fail;
} }
@ -224,13 +224,9 @@ aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
static bool static bool
aot_compile_simd_extract(AOTCompContext *comp_ctx, aot_compile_simd_extract(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 lane_id, bool need_extend, bool is_signed,
uint8 lane_id, LLVMTypeRef vector_type, LLVMTypeRef result_type,
bool need_extend,
bool is_signed,
LLVMTypeRef vector_type,
LLVMTypeRef result_type,
unsigned aot_value_type) unsigned aot_value_type)
{ {
LLVMValueRef vector, lane, result; LLVMValueRef vector, lane, result;
@ -256,16 +252,16 @@ aot_compile_simd_extract(AOTCompContext *comp_ctx,
if (need_extend) { if (need_extend) {
if (is_signed) { if (is_signed) {
/* sext <element_type> %element to <result_type> */ /* sext <element_type> %element to <result_type> */
if (!(result = LLVMBuildSExt(comp_ctx->builder, result, if (!(result = LLVMBuildSExt(comp_ctx->builder, result, result_type,
result_type, "ret"))) { "ret"))) {
HANDLE_FAILURE("LLVMBuildSExt"); HANDLE_FAILURE("LLVMBuildSExt");
goto fail; goto fail;
} }
} }
else { else {
/* sext <element_type> %element to <result_type> */ /* sext <element_type> %element to <result_type> */
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, if (!(result = LLVMBuildZExt(comp_ctx->builder, result, result_type,
result_type, "ret"))) { "ret"))) {
HANDLE_FAILURE("LLVMBuildZExt"); HANDLE_FAILURE("LLVMBuildZExt");
goto fail; goto fail;
} }
@ -281,8 +277,7 @@ fail:
bool bool
aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id,
uint8 lane_id,
bool is_signed) bool is_signed)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, true, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, true,
@ -292,8 +287,7 @@ aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id,
uint8 lane_id,
bool is_signed) bool is_signed)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, true, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, true,
@ -303,8 +297,7 @@ aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
V128_i32x4_TYPE, I32_TYPE, VALUE_TYPE_I32); V128_i32x4_TYPE, I32_TYPE, VALUE_TYPE_I32);
@ -312,8 +305,7 @@ aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
V128_i64x2_TYPE, I64_TYPE, VALUE_TYPE_I64); V128_i64x2_TYPE, I64_TYPE, VALUE_TYPE_I64);
@ -321,8 +313,7 @@ aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx, aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
V128_f32x4_TYPE, F32_TYPE, VALUE_TYPE_F32); V128_f32x4_TYPE, F32_TYPE, VALUE_TYPE_F32);
@ -330,20 +321,16 @@ aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx, aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false, return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
V128_f64x2_TYPE, F64_TYPE, VALUE_TYPE_F64); V128_f64x2_TYPE, F64_TYPE, VALUE_TYPE_F64);
} }
static bool static bool
aot_compile_simd_replace(AOTCompContext *comp_ctx, aot_compile_simd_replace(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 lane_id, unsigned new_value_type,
uint8 lane_id, LLVMTypeRef vector_type, bool need_reduce,
unsigned new_value_type,
LLVMTypeRef vector_type,
bool need_reduce,
LLVMTypeRef element_type) LLVMTypeRef element_type)
{ {
LLVMValueRef vector, new_value, lane, result; LLVMValueRef vector, new_value, lane, result;
@ -368,7 +355,8 @@ aot_compile_simd_replace(AOTCompContext *comp_ctx,
} }
} }
/* insertelement <vector_type> %vector, <element_type> %element, i32 lane */ /* insertelement <vector_type> %vector, <element_type> %element,
i32 lane */
if (!(result = LLVMBuildInsertElement(comp_ctx->builder, vector, new_value, if (!(result = LLVMBuildInsertElement(comp_ctx->builder, vector, new_value,
lane, "new_vector"))) { lane, "new_vector"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
@ -383,60 +371,48 @@ fail:
bool bool
aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
VALUE_TYPE_I32, V128_i8x16_TYPE, true, V128_i8x16_TYPE, true, INT8_TYPE);
INT8_TYPE);
} }
bool bool
aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
VALUE_TYPE_I32, V128_i16x8_TYPE, true, V128_i16x8_TYPE, true, INT16_TYPE);
INT16_TYPE);
} }
bool bool
aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
VALUE_TYPE_I32, V128_i32x4_TYPE, false, V128_i32x4_TYPE, false, I32_TYPE);
I32_TYPE);
} }
bool bool
aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I64,
VALUE_TYPE_I64, V128_i64x2_TYPE, false, V128_i64x2_TYPE, false, I64_TYPE);
I64_TYPE);
} }
bool bool
aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx, aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_F32,
VALUE_TYPE_F32, V128_f32x4_TYPE, false, V128_f32x4_TYPE, false, F32_TYPE);
F32_TYPE);
} }
bool bool
aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx, aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id)
uint8 lane_id)
{ {
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_F64,
VALUE_TYPE_F64, V128_f64x2_TYPE, false, V128_f64x2_TYPE, false, F64_TYPE);
F64_TYPE);
} }

View File

@ -13,8 +13,7 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_shuffle(AOTCompContext *comp_ctx, aot_compile_simd_shuffle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
const uint8 *frame_ip); const uint8 *frame_ip);
bool bool
@ -22,84 +21,68 @@ aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id,
uint8 lane_id,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id,
uint8 lane_id,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx, aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx, aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx, aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
uint8 lane_id);
bool bool
aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx, aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, uint8 lane_id);
bool
aot_compile_simd_load8_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 lane_id); uint8 lane_id);
bool bool
aot_compile_simd_load8_lane(AOTCompContext *comp_ctx, aot_compile_simd_load16_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 lane_id); uint8 lane_id);
bool bool
aot_compile_simd_load16_lane(AOTCompContext *comp_ctx, aot_compile_simd_load32_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 lane_id); uint8 lane_id);
bool bool
aot_compile_simd_load32_lane(AOTCompContext *comp_ctx, aot_compile_simd_load64_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 lane_id);
bool
aot_compile_simd_load64_lane(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx,
uint8 lane_id); uint8 lane_id);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -16,10 +16,8 @@ enum integer_shift {
}; };
static bool static bool
simd_shift(AOTCompContext *comp_ctx, simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, IntShift shift_op, enum integer_shift itype)
IntShift shift_op,
enum integer_shift itype)
{ {
LLVMValueRef vector, offset, result = NULL; LLVMValueRef vector, offset, result = NULL;
LLVMTypeRef vector_type[] = { V128_i8x16_TYPE, V128_i16x8_TYPE, LLVMTypeRef vector_type[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
@ -27,8 +25,7 @@ simd_shift(AOTCompContext *comp_ctx,
LLVMTypeRef element_type[] = { INT8_TYPE, INT16_TYPE, I32_TYPE, I64_TYPE }; LLVMTypeRef element_type[] = { INT8_TYPE, INT16_TYPE, I32_TYPE, I64_TYPE };
LLVMValueRef undef[] = { LLVM_CONST(i8x16_undef), LLVM_CONST(i16x8_undef), LLVMValueRef undef[] = { LLVM_CONST(i8x16_undef), LLVM_CONST(i16x8_undef),
LLVM_CONST(i32x4_undef), LLVM_CONST(i32x4_undef), LLVM_CONST(i64x2_undef) };
LLVM_CONST(i64x2_undef) };
LLVMValueRef mask[] = { LLVM_CONST(i8x16_vec_zero), LLVMValueRef mask[] = { LLVM_CONST(i8x16_vec_zero),
LLVM_CONST(i16x8_vec_zero), LLVM_CONST(i16x8_vec_zero),
LLVM_CONST(i32x4_vec_zero), LLVM_CONST(i32x4_vec_zero),
@ -49,8 +46,8 @@ simd_shift(AOTCompContext *comp_ctx,
/* offset mod LaneBits */ /* offset mod LaneBits */
if (!lane_bits[itype] if (!lane_bits[itype]
|| !(offset = LLVMBuildSRem(comp_ctx->builder, offset, || !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype],
lane_bits[itype], "offset_fix"))) { "offset_fix"))) {
HANDLE_FAILURE("LLVMBuildSRem"); HANDLE_FAILURE("LLVMBuildSRem");
return false; return false;
} }
@ -119,32 +116,28 @@ fail:
} }
bool bool
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op) IntShift shift_op)
{ {
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i8x16); return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i8x16);
} }
bool bool
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op) IntShift shift_op)
{ {
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i16x8); return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i16x8);
} }
bool bool
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op) IntShift shift_op)
{ {
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i32x4); return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i32x4);
} }
bool bool
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op) IntShift shift_op)
{ {
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i64x2); return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i64x2);

View File

@ -13,23 +13,19 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op); IntShift shift_op);
bool bool
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op); IntShift shift_op);
bool bool
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op); IntShift shift_op);
bool bool
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
IntShift shift_op); IntShift shift_op);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -64,8 +64,8 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
} }
if (e_bitmask_i64x2 != itype) { if (e_bitmask_i64x2 != itype) {
if (!(vector = LLVMBuildSExt(comp_ctx->builder, vector, if (!(vector = LLVMBuildSExt(comp_ctx->builder, vector, vector_ext_type,
vector_ext_type, "zext_to_i64"))) { "zext_to_i64"))) {
goto fail; goto fail;
} }
} }
@ -74,8 +74,8 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
mask_element[i] = 0x1 << i; mask_element[i] = 0x1 << i;
} }
if (!(mask = simd_build_const_integer_vector( if (!(mask = simd_build_const_integer_vector(comp_ctx, I64_TYPE,
comp_ctx, I64_TYPE, mask_element, lanes[itype]))) { mask_element, lanes[itype]))) {
goto fail; goto fail;
} }

View File

@ -8,8 +8,7 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
static bool static bool
v128_bitwise_two_component(AOTCompContext *comp_ctx, v128_bitwise_two_component(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Bitwise bitwise_op) V128Bitwise bitwise_op)
{ {
LLVMValueRef vector1, vector2, result; LLVMValueRef vector1, vector2, result;
@ -126,8 +125,7 @@ fail:
bool bool
aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx, aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, V128Bitwise bitwise_op)
V128Bitwise bitwise_op)
{ {
switch (bitwise_op) { switch (bitwise_op) {
case V128_AND: case V128_AND:

View File

@ -14,8 +14,7 @@ extern "C" {
bool bool
aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx, aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, V128Bitwise bitwise_op);
V128Bitwise bitwise_op);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */

View File

@ -16,8 +16,7 @@ enum integer_all_true {
}; };
static bool static bool
simd_all_true(AOTCompContext *comp_ctx, simd_all_true(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
enum integer_all_true itype) enum integer_all_true itype)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
@ -56,9 +55,9 @@ simd_all_true(AOTCompContext *comp_ctx,
} }
/* check zero */ /* check zero */
if (!(result = aot_call_llvm_intrinsic(comp_ctx, func_ctx, if (!(result =
intrinsic[itype], INT1_TYPE, aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
&vector_i1_type, 1, result))) { INT1_TYPE, &vector_i1_type, 1, result))) {
goto fail; goto fail;
} }

View File

@ -7,8 +7,7 @@
LLVMValueRef LLVMValueRef
simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx, simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, LLVMTypeRef vec_type,
LLVMTypeRef vec_type,
const char *name) const char *name)
{ {
LLVMValueRef number; LLVMValueRef number;
@ -28,8 +27,7 @@ fail:
bool bool
simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx, simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, LLVMValueRef vector,
LLVMValueRef vector,
const char *name) const char *name)
{ {
if (!(vector = LLVMBuildBitCast(comp_ctx->builder, vector, V128_i64x2_TYPE, if (!(vector = LLVMBuildBitCast(comp_ctx->builder, vector, V128_i64x2_TYPE,
@ -66,8 +64,7 @@ simd_lane_id_to_llvm_value(AOTCompContext *comp_ctx, uint8 lane_id)
LLVMValueRef LLVMValueRef
simd_build_const_integer_vector(const AOTCompContext *comp_ctx, simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const int *element_value, const int *element_value, uint32 length)
uint32 length)
{ {
LLVMValueRef vector = NULL; LLVMValueRef vector = NULL;
LLVMValueRef *elements; LLVMValueRef *elements;
@ -98,8 +95,7 @@ fail:
LLVMValueRef LLVMValueRef
simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx, simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const int64 element_value, const int64 element_value, uint32 length)
uint32 length)
{ {
LLVMValueRef vector = NULL, element; LLVMValueRef vector = NULL, element;
LLVMValueRef *elements; LLVMValueRef *elements;
@ -131,8 +127,7 @@ fail:
LLVMValueRef LLVMValueRef
simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx, simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const float element_value, const float element_value, uint32 length)
uint32 length)
{ {
LLVMValueRef vector = NULL, element; LLVMValueRef vector = NULL, element;
LLVMValueRef *elements; LLVMValueRef *elements;

View File

@ -17,14 +17,12 @@ is_target_x86(AOTCompContext *comp_ctx)
LLVMValueRef LLVMValueRef
simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx, simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, LLVMTypeRef vec_type,
LLVMTypeRef vec_type,
const char *name); const char *name);
bool bool
simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx, simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const AOTFuncContext *func_ctx, LLVMValueRef vector,
LLVMValueRef vector,
const char *name); const char *name);
LLVMValueRef LLVMValueRef
@ -33,18 +31,15 @@ simd_lane_id_to_llvm_value(AOTCompContext *comp_ctx, uint8 lane_id);
LLVMValueRef LLVMValueRef
simd_build_const_integer_vector(const AOTCompContext *comp_ctx, simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const int *element_value, const int *element_value, uint32 length);
uint32 length);
LLVMValueRef LLVMValueRef
simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx, simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const int64 element_value, const int64 element_value, uint32 length);
uint32 length);
LLVMValueRef LLVMValueRef
simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx, simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx,
const LLVMTypeRef element_type, const LLVMTypeRef element_type,
const float element_value, const float element_value, uint32 length);
uint32 length);
#endif /* _SIMD_COMMON_H_ */ #endif /* _SIMD_COMMON_H_ */

View File

@ -86,10 +86,8 @@ fail:
} }
static bool static bool
interger_vector_compare(AOTCompContext *comp_ctx, interger_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, IntCond cond, LLVMTypeRef vector_type)
IntCond cond,
LLVMTypeRef vector_type)
{ {
LLVMValueRef vec1, vec2, result; LLVMValueRef vec1, vec2, result;
LLVMIntPredicate int_pred; LLVMIntPredicate int_pred;
@ -138,41 +136,35 @@ fail:
bool bool
aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond)
IntCond cond)
{ {
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i8x16_TYPE); return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i8x16_TYPE);
} }
bool bool
aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond)
IntCond cond)
{ {
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i16x8_TYPE); return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i16x8_TYPE);
} }
bool bool
aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond)
IntCond cond)
{ {
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i32x4_TYPE); return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i32x4_TYPE);
} }
bool bool
aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond)
IntCond cond)
{ {
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i64x2_TYPE); return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i64x2_TYPE);
} }
static bool static bool
float_vector_compare(AOTCompContext *comp_ctx, float_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, FloatCond cond, LLVMTypeRef vector_type,
FloatCond cond,
LLVMTypeRef vector_type,
LLVMTypeRef result_type) LLVMTypeRef result_type)
{ {
LLVMValueRef vec1, vec2, result; LLVMValueRef vec1, vec2, result;
@ -222,8 +214,7 @@ fail:
bool bool
aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, FloatCond cond)
FloatCond cond)
{ {
return float_vector_compare(comp_ctx, func_ctx, cond, V128_f32x4_TYPE, return float_vector_compare(comp_ctx, func_ctx, cond, V128_f32x4_TYPE,
V128_i32x4_TYPE); V128_i32x4_TYPE);
@ -231,8 +222,7 @@ aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, FloatCond cond)
FloatCond cond)
{ {
return float_vector_compare(comp_ctx, func_ctx, cond, V128_f64x2_TYPE, return float_vector_compare(comp_ctx, func_ctx, cond, V128_f64x2_TYPE,
V128_i64x2_TYPE); V128_i64x2_TYPE);

View File

@ -14,33 +14,27 @@ extern "C" {
bool bool
aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond);
IntCond cond);
bool bool
aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond);
IntCond cond);
bool bool
aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond);
IntCond cond);
bool bool
aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, IntCond cond);
IntCond cond);
bool bool
aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, FloatCond cond);
FloatCond cond);
bool bool
aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, FloatCond cond);
FloatCond cond);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */

View File

@ -10,8 +10,7 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
bool bool
aot_compile_simd_v128_const(AOTCompContext *comp_ctx, aot_compile_simd_v128_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
const uint8 *imm_bytes) const uint8 *imm_bytes)
{ {
uint64 imm1, imm2; uint64 imm1, imm2;
@ -51,8 +50,7 @@ fail:
} }
bool bool
aot_compile_simd_splat(AOTCompContext *comp_ctx, aot_compile_simd_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 opcode) uint8 opcode)
{ {
uint32 opcode_index = opcode - SIMD_i8x16_splat; uint32 opcode_index = opcode - SIMD_i8x16_splat;
@ -63,9 +61,8 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
LLVM_CONST(f32x4_undef), LLVM_CONST(f64x2_undef), LLVM_CONST(f32x4_undef), LLVM_CONST(f64x2_undef),
}; };
LLVMValueRef masks[] = { LLVMValueRef masks[] = {
LLVM_CONST(i32x16_zero), LLVM_CONST(i32x8_zero), LLVM_CONST(i32x16_zero), LLVM_CONST(i32x8_zero), LLVM_CONST(i32x4_zero),
LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero), LLVM_CONST(i32x2_zero), LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero),
LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero),
}; };
switch (opcode) { switch (opcode) {
@ -118,8 +115,7 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
} }
/* insertelement <n x ty> undef, ty %value, i32 0 */ /* insertelement <n x ty> undef, ty %value, i32 0 */
if (!(base = if (!(base = LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
value, I32_ZERO, "base"))) { value, I32_ZERO, "base"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
goto fail; goto fail;
@ -127,14 +123,13 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
/* shufflevector <ty1> %base, <ty2> undef, <n x i32> zeroinitializer */ /* shufflevector <ty1> %base, <ty2> undef, <n x i32> zeroinitializer */
if (!(new_vector = LLVMBuildShuffleVector( if (!(new_vector = LLVMBuildShuffleVector(
comp_ctx->builder, base, undefs[opcode_index], masks[opcode_index], comp_ctx->builder, base, undefs[opcode_index],
"new_vector"))) { masks[opcode_index], "new_vector"))) {
HANDLE_FAILURE("LLVMBuildShuffleVector"); HANDLE_FAILURE("LLVMBuildShuffleVector");
goto fail; goto fail;
} }
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, new_vector, return simd_bitcast_and_push_v128(comp_ctx, func_ctx, new_vector, "result");
"result");
fail: fail:
return false; return false;
} }

View File

@ -13,13 +13,11 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_v128_const(AOTCompContext *comp_ctx, aot_compile_simd_v128_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
const uint8 *imm_bytes); const uint8 *imm_bytes);
bool bool
aot_compile_simd_splat(AOTCompContext *comp_ctx, aot_compile_simd_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 splat_opcode); uint8 splat_opcode);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -10,10 +10,8 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
static bool static bool
simd_integer_narrow_x86(AOTCompContext *comp_ctx, simd_integer_narrow_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef in_vector_type, LLVMTypeRef out_vector_type,
LLVMTypeRef in_vector_type,
LLVMTypeRef out_vector_type,
const char *instrinsic) const char *instrinsic)
{ {
LLVMValueRef vector1, vector2, result; LLVMValueRef vector1, vector2, result;
@ -44,13 +42,9 @@ enum integer_sat_type {
}; };
static LLVMValueRef static LLVMValueRef
simd_saturate(AOTCompContext *comp_ctx, simd_saturate(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, enum integer_sat_type itype, LLVMValueRef vector,
enum integer_sat_type itype, LLVMValueRef min, LLVMValueRef max, bool is_signed)
LLVMValueRef vector,
LLVMValueRef min,
LLVMValueRef max,
bool is_signed)
{ {
LLVMValueRef result; LLVMValueRef result;
LLVMTypeRef vector_type; LLVMTypeRef vector_type;
@ -115,10 +109,8 @@ simd_saturate(AOTCompContext *comp_ctx,
} }
static bool static bool
simd_integer_narrow_common(AOTCompContext *comp_ctx, simd_integer_narrow_common(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, enum integer_sat_type itype, bool is_signed)
enum integer_sat_type itype,
bool is_signed)
{ {
LLVMValueRef vec1, vec2, min, max, mask, result; LLVMValueRef vec1, vec2, min, max, mask, result;
LLVMTypeRef in_vector_type[] = { V128_i16x8_TYPE, V128_i32x4_TYPE, LLVMTypeRef in_vector_type[] = { V128_i16x8_TYPE, V128_i32x4_TYPE,
@ -152,8 +144,8 @@ simd_integer_narrow_common(AOTCompContext *comp_ctx,
if (!(vec2 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, if (!(vec2 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
in_vector_type[itype], "vec2")) in_vector_type[itype], "vec2"))
|| !(vec1 = simd_pop_v128_and_bitcast( || !(vec1 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
comp_ctx, func_ctx, in_vector_type[itype], "vec1"))) { in_vector_type[itype], "vec1"))) {
return false; return false;
} }
@ -200,8 +192,7 @@ simd_integer_narrow_common(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
if (is_target_x86(comp_ctx)) { if (is_target_x86(comp_ctx)) {
return simd_integer_narrow_x86( return simd_integer_narrow_x86(
@ -217,8 +208,7 @@ aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
if (is_target_x86(comp_ctx)) { if (is_target_x86(comp_ctx)) {
return simd_integer_narrow_x86(comp_ctx, func_ctx, V128_i32x4_TYPE, return simd_integer_narrow_x86(comp_ctx, func_ctx, V128_i32x4_TYPE,
@ -234,8 +224,7 @@ aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
/* TODO: x86 intrinsics */ /* TODO: x86 intrinsics */
return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i64x2, return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i64x2,
@ -249,12 +238,9 @@ enum integer_extend_type {
}; };
static LLVMValueRef static LLVMValueRef
simd_integer_extension(AOTCompContext *comp_ctx, simd_integer_extension(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, enum integer_extend_type itype, LLVMValueRef vector,
enum integer_extend_type itype, bool lower_half, bool is_signed)
LLVMValueRef vector,
bool lower_half,
bool is_signed)
{ {
LLVMValueRef mask, sub_vector, result; LLVMValueRef mask, sub_vector, result;
LLVMValueRef bits[] = { LLVMValueRef bits[] = {
@ -308,8 +294,7 @@ simd_integer_extension(AOTCompContext *comp_ctx,
static bool static bool
simd_integer_extension_wrapper(AOTCompContext *comp_ctx, simd_integer_extension_wrapper(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
enum integer_extend_type itype, enum integer_extend_type itype, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
@ -332,8 +317,7 @@ simd_integer_extension_wrapper(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i8x16, return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i8x16,
@ -342,8 +326,7 @@ aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i16x8, return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i16x8,
@ -352,8 +335,7 @@ aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i32x4, return simd_integer_extension_wrapper(comp_ctx, func_ctx, e_ext_i32x4,
@ -361,17 +343,15 @@ aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
simd_trunc_sat(AOTCompContext *comp_ctx, simd_trunc_sat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, const char *intrinsics, LLVMTypeRef in_vector_type,
const char *intrinsics,
LLVMTypeRef in_vector_type,
LLVMTypeRef out_vector_type) LLVMTypeRef out_vector_type)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
LLVMTypeRef param_types[] = { in_vector_type }; LLVMTypeRef param_types[] = { in_vector_type };
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, in_vector_type,
in_vector_type, "vector"))) { "vector"))) {
return false; return false;
} }
@ -386,8 +366,7 @@ simd_trunc_sat(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_trunc_sat_f32x4(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_trunc_sat_f32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
LLVMValueRef result; LLVMValueRef result;
if (!(result = simd_trunc_sat(comp_ctx, func_ctx, if (!(result = simd_trunc_sat(comp_ctx, func_ctx,
@ -402,8 +381,7 @@ aot_compile_simd_i32x4_trunc_sat_f32x4(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
LLVMValueRef result, zero, mask; LLVMValueRef result, zero, mask;
LLVMTypeRef out_vector_type; LLVMTypeRef out_vector_type;
@ -437,8 +415,8 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
return false; return false;
} }
if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result, zero, if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result, zero, mask,
mask, "extend"))) { "extend"))) {
HANDLE_FAILURE("LLVMBuildShuffleVector"); HANDLE_FAILURE("LLVMBuildShuffleVector");
return false; return false;
} }
@ -447,10 +425,8 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
} }
static LLVMValueRef static LLVMValueRef
simd_integer_convert(AOTCompContext *comp_ctx, simd_integer_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, bool is_signed, LLVMValueRef vector,
bool is_signed,
LLVMValueRef vector,
LLVMTypeRef out_vector_type) LLVMTypeRef out_vector_type)
{ {
@ -468,8 +444,7 @@ simd_integer_convert(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
@ -488,8 +463,7 @@ aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed)
bool is_signed)
{ {
LLVMValueRef vector, mask, result; LLVMValueRef vector, mask, result;
LLVMValueRef lanes[] = { LLVMValueRef lanes[] = {
@ -529,10 +503,8 @@ aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
} }
static bool static bool
simd_extadd_pairwise(AOTCompContext *comp_ctx, simd_extadd_pairwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef in_vector_type, LLVMTypeRef out_vector_type,
LLVMTypeRef in_vector_type,
LLVMTypeRef out_vector_type,
bool is_signed) bool is_signed)
{ {
LLVMValueRef vector, even_mask, odd_mask, sub_vector_even, sub_vector_odd, LLVMValueRef vector, even_mask, odd_mask, sub_vector_even, sub_vector_odd,
@ -554,8 +526,8 @@ simd_extadd_pairwise(AOTCompContext *comp_ctx,
/* assumption about i16x8 from i8x16 and i32x4 from i16x8 */ /* assumption about i16x8 from i8x16 and i32x4 from i16x8 */
uint8 mask_length = V128_i16x8_TYPE == out_vector_type ? 8 : 4; uint8 mask_length = V128_i16x8_TYPE == out_vector_type ? 8 : 4;
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, in_vector_type,
in_vector_type, "vector"))) { "vector"))) {
return false; return false;
} }
@ -706,10 +678,8 @@ enum integer_extmul_type {
}; };
static bool static bool
simd_integer_extmul(AOTCompContext *comp_ctx, simd_integer_extmul(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, bool lower_half, bool is_signed,
bool lower_half,
bool is_signed,
enum integer_extmul_type itype) enum integer_extmul_type itype)
{ {
LLVMValueRef vec1, vec2, result; LLVMValueRef vec1, vec2, result;
@ -726,8 +696,8 @@ simd_integer_extmul(AOTCompContext *comp_ctx,
if (!(vec1 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, if (!(vec1 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
in_vector_type[itype], "vec1")) in_vector_type[itype], "vec1"))
|| !(vec2 = simd_pop_v128_and_bitcast( || !(vec2 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
comp_ctx, func_ctx, in_vector_type[itype], "vec2"))) { in_vector_type[itype], "vec2"))) {
return false; return false;
} }
@ -747,8 +717,7 @@ simd_integer_extmul(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed, return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed,
@ -757,8 +726,7 @@ aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed, return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed,
@ -767,8 +735,7 @@ aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed) bool is_signed)
{ {
return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed, return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed,

View File

@ -14,35 +14,29 @@ extern "C" {
bool bool
aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_low,
bool is_low,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_low,
bool is_low,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed); bool is_signed);
bool bool
@ -57,13 +51,11 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i16x8_extadd_pairwise_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_extadd_pairwise_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
@ -79,20 +71,17 @@ aot_compile_simd_i16x8_q15mulr_sat(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_low,
bool is_low,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool is_low,
bool is_low,
bool is_signed); bool is_signed);
bool bool
aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool lower_half,
bool lower_half,
bool is_signed); bool is_signed);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */

View File

@ -10,10 +10,8 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
static bool static bool
simd_v128_float_arith(AOTCompContext *comp_ctx, simd_v128_float_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, FloatArithmetic arith_op, LLVMTypeRef vector_type)
FloatArithmetic arith_op,
LLVMTypeRef vector_type)
{ {
LLVMValueRef lhs, rhs, result = NULL; LLVMValueRef lhs, rhs, result = NULL;
@ -51,26 +49,21 @@ simd_v128_float_arith(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op) FloatArithmetic arith_op)
{ {
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, V128_f32x4_TYPE);
V128_f32x4_TYPE);
} }
bool bool
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op) FloatArithmetic arith_op)
{ {
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, V128_f64x2_TYPE);
V128_f64x2_TYPE);
} }
static bool static bool
simd_v128_float_neg(AOTCompContext *comp_ctx, simd_v128_float_neg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
LLVMTypeRef vector_type) LLVMTypeRef vector_type)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
@ -101,10 +94,8 @@ aot_compile_simd_f64x2_neg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
static bool static bool
simd_float_intrinsic(AOTCompContext *comp_ctx, simd_float_intrinsic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef vector_type, const char *intrinsic)
LLVMTypeRef vector_type,
const char *intrinsic)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
LLVMTypeRef param_types[1] = { vector_type }; LLVMTypeRef param_types[1] = { vector_type };
@ -115,8 +106,8 @@ simd_float_intrinsic(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, vector_type, aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
param_types, 1, vector))) { vector_type, param_types, 1, vector))) {
HANDLE_FAILURE("LLVMBuildCall"); HANDLE_FAILURE("LLVMBuildCall");
return false; return false;
} }
@ -139,16 +130,14 @@ aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
bool bool
aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
"llvm.round.v4f32"); "llvm.round.v4f32");
} }
bool bool
aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
"llvm.round.v2f64"); "llvm.round.v2f64");
@ -183,32 +172,28 @@ aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
bool bool
aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
"llvm.floor.v4f32"); "llvm.floor.v4f32");
} }
bool bool
aot_compile_simd_f64x2_floor(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_floor(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
"llvm.floor.v2f64"); "llvm.floor.v2f64");
} }
bool bool
aot_compile_simd_f32x4_trunc(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
"llvm.trunc.v4f32"); "llvm.trunc.v4f32");
} }
bool bool
aot_compile_simd_f64x2_trunc(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
AOTFuncContext *func_ctx)
{ {
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE, return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
"llvm.trunc.v2f64"); "llvm.trunc.v2f64");
@ -231,10 +216,8 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx,
} }
static bool static bool
simd_float_cmp(AOTCompContext *comp_ctx, simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, FloatArithmetic arith_op, LLVMTypeRef vector_type)
FloatArithmetic arith_op,
LLVMTypeRef vector_type)
{ {
LLVMValueRef lhs, rhs, result; LLVMValueRef lhs, rhs, result;
LLVMRealPredicate op = FLOAT_MIN == arith_op ? LLVMRealULT : LLVMRealUGT; LLVMRealPredicate op = FLOAT_MIN == arith_op ? LLVMRealULT : LLVMRealUGT;
@ -260,11 +243,11 @@ simd_float_cmp(AOTCompContext *comp_ctx,
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result"); return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
} }
/*TODO: sugggest non-IA platforms check with "llvm.minimum.*" and "llvm.maximum.*" firstly */ /*TODO: sugggest non-IA platforms check with "llvm.minimum.*" and
* "llvm.maximum.*" firstly */
bool bool
aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min)
bool run_min)
{ {
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f32x4_TYPE); V128_f32x4_TYPE);
@ -272,18 +255,15 @@ aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min)
bool run_min)
{ {
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f64x2_TYPE); V128_f64x2_TYPE);
} }
static bool static bool
simd_float_pmin_max(AOTCompContext *comp_ctx, simd_float_pmin_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef vector_type, const char *intrinsic)
LLVMTypeRef vector_type,
const char *intrinsic)
{ {
LLVMValueRef lhs, rhs, result; LLVMValueRef lhs, rhs, result;
LLVMTypeRef param_types[2]; LLVMTypeRef param_types[2];
@ -299,8 +279,8 @@ simd_float_pmin_max(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, vector_type, aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
param_types, 2, lhs, rhs))) { vector_type, param_types, 2, lhs, rhs))) {
return false; return false;
} }
@ -309,8 +289,7 @@ simd_float_pmin_max(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min)
bool run_min)
{ {
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f32x4_TYPE, return simd_float_pmin_max(comp_ctx, func_ctx, V128_f32x4_TYPE,
run_min ? "llvm.minnum.v4f32" run_min ? "llvm.minnum.v4f32"
@ -319,8 +298,7 @@ aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min)
bool run_min)
{ {
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f64x2_TYPE, return simd_float_pmin_max(comp_ctx, func_ctx, V128_f64x2_TYPE,
run_min ? "llvm.minnum.v2f64" run_min ? "llvm.minnum.v2f64"
@ -340,8 +318,8 @@ aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx,
if (!(elem_0 = LLVMBuildExtractElement(comp_ctx->builder, vector, if (!(elem_0 = LLVMBuildExtractElement(comp_ctx->builder, vector,
LLVM_CONST(i32_zero), "elem_0")) LLVM_CONST(i32_zero), "elem_0"))
|| !(elem_1 = LLVMBuildExtractElement( || !(elem_1 = LLVMBuildExtractElement(comp_ctx->builder, vector,
comp_ctx->builder, vector, LLVM_CONST(i32_one), "elem_1"))) { LLVM_CONST(i32_one), "elem_1"))) {
HANDLE_FAILURE("LLVMBuildExtractElement"); HANDLE_FAILURE("LLVMBuildExtractElement");
return false; return false;
} }
@ -355,8 +333,8 @@ aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx,
return false; return false;
} }
if (!(result = LLVMBuildInsertElement( if (!(result = LLVMBuildInsertElement(comp_ctx->builder,
comp_ctx->builder, LLVM_CONST(f32x4_vec_zero), elem_0, LLVM_CONST(f32x4_vec_zero), elem_0,
LLVM_CONST(i32_zero), "new_vector_0")) LLVM_CONST(i32_zero), "new_vector_0"))
|| !(result = || !(result =
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1, LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,
@ -381,8 +359,8 @@ aot_compile_simd_f32x4_promote(AOTCompContext *comp_ctx,
if (!(elem_0 = LLVMBuildExtractElement(comp_ctx->builder, vector, if (!(elem_0 = LLVMBuildExtractElement(comp_ctx->builder, vector,
LLVM_CONST(i32_zero), "elem_0")) LLVM_CONST(i32_zero), "elem_0"))
|| !(elem_1 = LLVMBuildExtractElement( || !(elem_1 = LLVMBuildExtractElement(comp_ctx->builder, vector,
comp_ctx->builder, vector, LLVM_CONST(i32_one), "elem_1"))) { LLVM_CONST(i32_one), "elem_1"))) {
HANDLE_FAILURE("LLVMBuildExtractElement"); HANDLE_FAILURE("LLVMBuildExtractElement");
return false; return false;
} }
@ -396,8 +374,8 @@ aot_compile_simd_f32x4_promote(AOTCompContext *comp_ctx,
return false; return false;
} }
if (!(result = LLVMBuildInsertElement( if (!(result = LLVMBuildInsertElement(comp_ctx->builder,
comp_ctx->builder, LLVM_CONST(f64x2_vec_zero), elem_0, LLVM_CONST(f64x2_vec_zero), elem_0,
LLVM_CONST(i32_zero), "new_vector_0")) LLVM_CONST(i32_zero), "new_vector_0"))
|| !(result = || !(result =
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1, LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,

View File

@ -13,13 +13,11 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op); FloatArithmetic arith_op);
bool bool
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
FloatArithmetic arith_op); FloatArithmetic arith_op);
bool bool
@ -43,20 +41,16 @@ aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx); AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_f64x2_sqrt(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_f32x4_ceil(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx,
@ -84,23 +78,19 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min);
bool run_min);
bool bool
aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min);
bool run_min);
bool bool
aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx, aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min);
bool run_min);
bool bool
aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx, bool run_min);
bool run_min);
bool bool
aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx, aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx,

View File

@ -9,10 +9,8 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
static bool static bool
simd_integer_arith(AOTCompContext *comp_ctx, simd_integer_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, LLVMTypeRef vector_type)
V128Arithmetic arith_op,
LLVMTypeRef vector_type)
{ {
LLVMValueRef lhs, rhs, result = NULL; LLVMValueRef lhs, rhs, result = NULL;
@ -47,32 +45,28 @@ simd_integer_arith(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic arith_op) V128Arithmetic arith_op)
{ {
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i8x16_TYPE); return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i8x16_TYPE);
} }
bool bool
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic arith_op) V128Arithmetic arith_op)
{ {
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i16x8_TYPE); return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i16x8_TYPE);
} }
bool bool
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic arith_op) V128Arithmetic arith_op)
{ {
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i32x4_TYPE); return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i32x4_TYPE);
} }
bool bool
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic arith_op) V128Arithmetic arith_op)
{ {
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i64x2_TYPE); return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i64x2_TYPE);
@ -141,11 +135,8 @@ aot_compile_simd_i8x16_popcnt(AOTCompContext *comp_ctx,
} }
static bool static bool
simd_v128_cmp(AOTCompContext *comp_ctx, simd_v128_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef vector_type, V128Arithmetic arith_op, bool is_signed)
LLVMTypeRef vector_type,
V128Arithmetic arith_op,
bool is_signed)
{ {
LLVMValueRef lhs, rhs, result; LLVMValueRef lhs, rhs, result;
LLVMIntPredicate op; LLVMIntPredicate op;
@ -179,30 +170,24 @@ simd_v128_cmp(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed)
V128Arithmetic arith_op,
bool is_signed)
{ {
return simd_v128_cmp(comp_ctx, func_ctx, V128_i8x16_TYPE, arith_op, return simd_v128_cmp(comp_ctx, func_ctx, V128_i8x16_TYPE, arith_op,
is_signed); is_signed);
} }
bool bool
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed)
V128Arithmetic arith_op,
bool is_signed)
{ {
return simd_v128_cmp(comp_ctx, func_ctx, V128_i16x8_TYPE, arith_op, return simd_v128_cmp(comp_ctx, func_ctx, V128_i16x8_TYPE, arith_op,
is_signed); is_signed);
} }
bool bool
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed)
V128Arithmetic arith_op,
bool is_signed)
{ {
return simd_v128_cmp(comp_ctx, func_ctx, V128_i32x4_TYPE, arith_op, return simd_v128_cmp(comp_ctx, func_ctx, V128_i32x4_TYPE, arith_op,
is_signed); is_signed);
@ -210,10 +195,8 @@ aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx,
/* llvm.abs.* */ /* llvm.abs.* */
static bool static bool
simd_v128_abs(AOTCompContext *comp_ctx, simd_v128_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, char *intrinsic, LLVMTypeRef vector_type)
char *intrinsic,
LLVMTypeRef vector_type)
{ {
LLVMValueRef vector, result; LLVMValueRef vector, result;
LLVMTypeRef param_types[] = { vector_type, INT1_TYPE }; LLVMTypeRef param_types[] = { vector_type, INT1_TYPE };
@ -236,29 +219,25 @@ simd_v128_abs(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v16i8", return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v16i8", V128_i8x16_TYPE);
V128_i8x16_TYPE);
} }
bool bool
aot_compile_simd_i16x8_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_simd_i16x8_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v8i16", return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v8i16", V128_i16x8_TYPE);
V128_i16x8_TYPE);
} }
bool bool
aot_compile_simd_i32x4_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_simd_i32x4_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v4i32", return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v4i32", V128_i32x4_TYPE);
V128_i32x4_TYPE);
} }
bool bool
aot_compile_simd_i64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_simd_i64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v2i64", return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v2i64", V128_i64x2_TYPE);
V128_i64x2_TYPE);
} }
enum integer_avgr_u { enum integer_avgr_u {
@ -270,8 +249,7 @@ enum integer_avgr_u {
/* TODO: try int_x86_mmx_pavg_b and int_x86_mmx_pavg_w */ /* TODO: try int_x86_mmx_pavg_b and int_x86_mmx_pavg_w */
/* (v1 + v2 + 1) / 2 */ /* (v1 + v2 + 1) / 2 */
static bool static bool
simd_v128_avg(AOTCompContext *comp_ctx, simd_v128_avg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
enum integer_avgr_u itype) enum integer_avgr_u itype)
{ {
LLVMValueRef lhs, rhs, ones, result; LLVMValueRef lhs, rhs, ones, result;
@ -324,8 +302,8 @@ simd_v128_avg(AOTCompContext *comp_ctx,
return false; return false;
} }
if (!(result = LLVMBuildTrunc(comp_ctx->builder, result, if (!(result = LLVMBuildTrunc(comp_ctx->builder, result, vector_type[itype],
vector_type[itype], "to_orig_type"))) { "to_orig_type"))) {
HANDLE_FAILURE("LLVMBuildTrunc"); HANDLE_FAILURE("LLVMBuildTrunc");
return false; return false;
} }
@ -406,8 +384,8 @@ aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
return false; return false;
} }
if (!(zero = if (!(zero = simd_build_splat_const_integer_vector(comp_ctx, I32_TYPE, 0,
simd_build_splat_const_integer_vector(comp_ctx, I32_TYPE, 0, 8))) { 8))) {
return false; return false;
} }

View File

@ -13,23 +13,19 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic cond); V128Arithmetic cond);
bool bool
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic cond); V128Arithmetic cond);
bool bool
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic cond); V128Arithmetic cond);
bool bool
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
V128Arithmetic cond); V128Arithmetic cond);
bool bool
@ -49,22 +45,16 @@ aot_compile_simd_i8x16_popcnt(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx); AOTFuncContext *func_ctx);
bool bool
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed);
V128Arithmetic arith_op,
bool is_signed);
bool bool
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed);
V128Arithmetic arith_op,
bool is_signed);
bool bool
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, V128Arithmetic arith_op, bool is_signed);
V128Arithmetic arith_op,
bool is_signed);
bool bool
aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);

View File

@ -12,12 +12,8 @@
/* data_length in bytes */ /* data_length in bytes */
static LLVMValueRef static LLVMValueRef
simd_load(AOTCompContext *comp_ctx, simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
AOTFuncContext *func_ctx, uint32 offset, uint32 data_length, LLVMTypeRef ptr_type)
uint32 align,
uint32 offset,
uint32 data_length,
LLVMTypeRef ptr_type)
{ {
LLVMValueRef maddr, data; LLVMValueRef maddr, data;
@ -44,15 +40,13 @@ simd_load(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 align, uint32 offset)
uint32 align,
uint32 offset)
{ {
LLVMValueRef result; LLVMValueRef result;
if (!(result = if (!(result = simd_load(comp_ctx, func_ctx, align, offset, 16,
simd_load(comp_ctx, func_ctx, align, offset, 16, V128_PTR_TYPE))) { V128_PTR_TYPE))) {
return false; return false;
} }
@ -64,11 +58,8 @@ fail:
} }
bool bool
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset)
uint8 opcode,
uint32 align,
uint32 offset)
{ {
LLVMValueRef sub_vector, result; LLVMValueRef sub_vector, result;
uint32 opcode_index = opcode - SIMD_v128_load8x8_s; uint32 opcode_index = opcode - SIMD_v128_load8x8_s;
@ -119,11 +110,8 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset)
uint8 opcode,
uint32 align,
uint32 offset)
{ {
uint32 opcode_index = opcode - SIMD_v128_load8_splat; uint32 opcode_index = opcode - SIMD_v128_load8_splat;
LLVMValueRef element, result; LLVMValueRef element, result;
@ -169,11 +157,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset,
uint8 opcode,
uint32 align,
uint32 offset,
uint8 lane_id) uint8 lane_id)
{ {
LLVMValueRef element, vector; LLVMValueRef element, vector;
@ -208,11 +193,8 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset)
uint8 opcode,
uint32 align,
uint32 offset)
{ {
LLVMValueRef element, result, mask; LLVMValueRef element, result, mask;
uint32 opcode_index = opcode - SIMD_v128_load32_zero; uint32 opcode_index = opcode - SIMD_v128_load32_zero;
@ -267,12 +249,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
/* data_length in bytes */ /* data_length in bytes */
static bool static bool
simd_store(AOTCompContext *comp_ctx, simd_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
AOTFuncContext *func_ctx, uint32 offset, uint32 data_length, LLVMValueRef value,
uint32 align,
uint32 offset,
uint32 data_length,
LLVMValueRef value,
LLVMTypeRef value_ptr_type) LLVMTypeRef value_ptr_type)
{ {
LLVMValueRef maddr, result; LLVMValueRef maddr, result;
@ -298,10 +276,8 @@ simd_store(AOTCompContext *comp_ctx,
} }
bool bool
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 align, uint32 offset)
uint32 align,
uint32 offset)
{ {
LLVMValueRef value; LLVMValueRef value;
@ -314,11 +290,8 @@ fail:
} }
bool bool
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset,
uint8 opcode,
uint32 align,
uint32 offset,
uint8 lane_id) uint8 lane_id)
{ {
LLVMValueRef element, vector; LLVMValueRef element, vector;

View File

@ -13,52 +13,33 @@ extern "C" {
#endif #endif
bool bool
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 align, uint32 offset);
uint32 align,
uint32 offset);
bool bool
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset);
uint8 opcode,
uint32 align,
uint32 offset);
bool bool
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset);
uint8 opcode,
uint32 align,
uint32 offset);
bool bool
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset,
uint8 opcode,
uint32 align,
uint32 offset,
uint8 lane_id); uint8 lane_id);
bool bool
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset);
uint8 opcode,
uint32 align,
uint32 offset);
bool bool
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint32 align, uint32 offset);
uint32 align,
uint32 offset);
bool bool
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, uint8 opcode, uint32 align, uint32 offset,
uint8 opcode,
uint32 align,
uint32 offset,
uint8 lane_id); uint8 lane_id);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -9,10 +9,8 @@
#include "../../aot/aot_runtime.h" #include "../../aot/aot_runtime.h"
static bool static bool
simd_sat_int_arith(AOTCompContext *comp_ctx, simd_sat_int_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx, LLVMTypeRef vector_type, const char *intrinsics)
LLVMTypeRef vector_type,
const char *intrinsics)
{ {
LLVMValueRef lhs, rhs, result; LLVMValueRef lhs, rhs, result;
LLVMTypeRef param_types[2]; LLVMTypeRef param_types[2];
@ -40,8 +38,7 @@ simd_sat_int_arith(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed)
bool is_signed)
{ {
char *intrinsics[][2] = { char *intrinsics[][2] = {
{ "llvm.sadd.sat.v16i8", "llvm.uadd.sat.v16i8" }, { "llvm.sadd.sat.v16i8", "llvm.uadd.sat.v16i8" },
@ -56,8 +53,7 @@ aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed)
bool is_signed)
{ {
char *intrinsics[][2] = { char *intrinsics[][2] = {
{ "llvm.sadd.sat.v8i16", "llvm.uadd.sat.v8i16" }, { "llvm.sadd.sat.v8i16", "llvm.uadd.sat.v8i16" },
@ -72,8 +68,7 @@ aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
bool bool
aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed)
bool is_signed)
{ {
char *intrinsics[][2] = { char *intrinsics[][2] = {
{ "llvm.sadd.sat.v4i32", "llvm.uadd.sat.v4i32" }, { "llvm.sadd.sat.v4i32", "llvm.uadd.sat.v4i32" },

View File

@ -15,20 +15,17 @@ extern "C" {
bool bool
aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed);
bool is_signed);
bool bool
aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx, aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, AOTFuncContext *func_ctx,
V128Arithmetic arith_op, V128Arithmetic arith_op, bool is_signed);
bool is_signed);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

View File

@ -59,8 +59,7 @@ control_thread_routine(void *arg)
control_thread->debug_engine = g_debug_engine; control_thread->debug_engine = g_debug_engine;
control_thread->debug_instance = debug_inst; control_thread->debug_instance = debug_inst;
strcpy(control_thread->ip_addr, g_debug_engine->ip_addr); strcpy(control_thread->ip_addr, g_debug_engine->ip_addr);
control_thread->port = control_thread->port = g_debug_engine->process_base_port + debug_inst->id;
g_debug_engine->process_base_port + debug_inst->id;
LOG_WARNING("control thread of debug object %p start at %s:%d\n", LOG_WARNING("control thread of debug object %p start at %s:%d\n",
debug_inst, control_thread->ip_addr, control_thread->port); debug_inst, control_thread->ip_addr, control_thread->port);
@ -123,7 +122,8 @@ wasm_debug_control_thread_create(WASMDebugInstance *debug_instance)
os_mutex_lock(&exec_env->wait_lock); os_mutex_lock(&exec_env->wait_lock);
if (0 != os_thread_create(&control_thread->tid, control_thread_routine, if (0
!= os_thread_create(&control_thread->tid, control_thread_routine,
debug_instance, APP_THREAD_STACK_SIZE_MAX)) { debug_instance, APP_THREAD_STACK_SIZE_MAX)) {
os_mutex_unlock(&control_thread->wait_lock); os_mutex_unlock(&control_thread->wait_lock);
goto fail1; goto fail1;
@ -153,8 +153,7 @@ wasm_debug_control_thread_destroy(WASMDebugInstance *debug_instance)
{ {
WASMDebugControlThread *control_thread = debug_instance->control_thread; WASMDebugControlThread *control_thread = debug_instance->control_thread;
LOG_VERBOSE("control thread of debug object %p stop at %s:%d\n", LOG_VERBOSE("control thread of debug object %p stop at %s:%d\n",
debug_instance, control_thread->ip_addr, debug_instance, control_thread->ip_addr, control_thread->port);
control_thread->port);
control_thread->status = STOPPED; control_thread->status = STOPPED;
os_mutex_lock(&control_thread->wait_lock); os_mutex_lock(&control_thread->wait_lock);
wasm_close_gdbserver(control_thread->server); wasm_close_gdbserver(control_thread->server);
@ -343,8 +342,7 @@ wasm_debug_instance_get_current_env(WASMDebugInstance *instance)
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
bool bool
wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance, wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
char name_buffer[], char name_buffer[], int len)
int len)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASIArguments *wasi_args; WASIArguments *wasi_args;
@ -392,8 +390,8 @@ wasm_debug_instance_get_tid(WASMDebugInstance *instance)
} }
int int
wasm_debug_instance_get_tids(WASMDebugInstance *instance, wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
uint64 tids[], int len) int len)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
int i = 0; int i = 0;
@ -411,8 +409,8 @@ wasm_debug_instance_get_tids(WASMDebugInstance *instance,
} }
uint64 uint64
wasm_debug_instance_wait_thread(WASMDebugInstance *instance, wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
uint64 tid, uint32 *status) uint32 *status)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMExecEnv *last_exec_env = NULL; WASMExecEnv *last_exec_env = NULL;
@ -454,8 +452,7 @@ wasm_debug_instance_get_pc(WASMDebugInstance *instance)
return 0; return 0;
exec_env = wasm_debug_instance_get_current_env(instance); exec_env = wasm_debug_instance_get_current_env(instance);
if ((exec_env->cur_frame != NULL) if ((exec_env->cur_frame != NULL) && (exec_env->cur_frame->ip != NULL)) {
&& (exec_env->cur_frame->ip != NULL)) {
WASMModuleInstance *module_inst = WASMModuleInstance *module_inst =
(WASMModuleInstance *)exec_env->module_inst; (WASMModuleInstance *)exec_env->module_inst;
return WASM_ADDR( return WASM_ADDR(
@ -519,7 +516,8 @@ wasm_debug_instance_get_memregion(WASMDebugInstance *instance, uint64 addr)
sprintf(mem_info->permisson, "%s", "rx"); sprintf(mem_info->permisson, "%s", "rx");
} }
break; break;
case WasmMemory: { case WasmMemory:
{
memory = module_inst->default_memory; memory = module_inst->default_memory;
if (memory) { if (memory) {
@ -549,8 +547,8 @@ wasm_debug_instance_destroy_memregion(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 offset,
uint64 offset, char *buf, uint64 *size) char *buf, uint64 *size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
@ -599,8 +597,8 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, uint64 offset,
uint64 offset, char *buf, uint64 *size) char *buf, uint64 *size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
@ -621,8 +619,7 @@ wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
num_bytes_per_page = memory->num_bytes_per_page; num_bytes_per_page = memory->num_bytes_per_page;
linear_mem_size = num_bytes_per_page * memory->cur_page_count; linear_mem_size = num_bytes_per_page * memory->cur_page_count;
if (offset + *size > linear_mem_size) { if (offset + *size > linear_mem_size) {
LOG_VERBOSE( LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
"wasm_debug_instance_get_linear_mem size over flow!\n");
*size = linear_mem_size >= offset ? linear_mem_size - offset : 0; *size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
} }
bh_memcpy_s(buf, *size, memory->memory_data + offset, *size); bh_memcpy_s(buf, *size, memory->memory_data + offset, *size);
@ -632,8 +629,8 @@ wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance, wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance, uint64 offset,
uint64 offset, char *buf, uint64 *size) char *buf, uint64 *size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
@ -654,8 +651,7 @@ wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance,
num_bytes_per_page = memory->num_bytes_per_page; num_bytes_per_page = memory->num_bytes_per_page;
linear_mem_size = num_bytes_per_page * memory->cur_page_count; linear_mem_size = num_bytes_per_page * memory->cur_page_count;
if (offset + *size > linear_mem_size) { if (offset + *size > linear_mem_size) {
LOG_VERBOSE( LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
"wasm_debug_instance_get_linear_mem size over flow!\n");
*size = linear_mem_size >= offset ? linear_mem_size - offset : 0; *size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
} }
bh_memcpy_s(memory->memory_data + offset, *size, buf, *size); bh_memcpy_s(memory->memory_data + offset, *size, buf, *size);
@ -665,8 +661,8 @@ wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_get_mem(WASMDebugInstance *instance, wasm_debug_instance_get_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
uint64 addr, char *buf, uint64 *size) uint64 *size)
{ {
switch (WASM_ADDR_TYPE(addr)) { switch (WASM_ADDR_TYPE(addr)) {
case WasmMemory: case WasmMemory:
@ -683,8 +679,8 @@ wasm_debug_instance_get_mem(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_set_mem(WASMDebugInstance *instance, wasm_debug_instance_set_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
uint64 addr, char *buf, uint64 *size) uint64 *size)
{ {
switch (WASM_ADDR_TYPE(addr)) { switch (WASM_ADDR_TYPE(addr)) {
case WasmMemory: case WasmMemory:
@ -713,8 +709,8 @@ wasm_exec_env_get_instance(WASMExecEnv *exec_env)
} }
int int
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
uint64 tid, uint64 buf[], uint64 size) uint64 buf[], uint64 size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
struct WASMInterpFrame *frame; struct WASMInterpFrame *frame;
@ -745,8 +741,8 @@ wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, uint64 addr,
uint64 addr, uint64 length) uint64 length)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
@ -770,22 +766,19 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
WASMDebugBreakPoint *breakpoint; WASMDebugBreakPoint *breakpoint;
if (!(breakpoint = if (!(breakpoint =
wasm_runtime_malloc(sizeof(WASMDebugBreakPoint)))) { wasm_runtime_malloc(sizeof(WASMDebugBreakPoint)))) {
LOG_ERROR( LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
"WASM Debug Engine error: failed to allocate memory");
return false; return false;
} }
memset(breakpoint, 0, sizeof(WASMDebugBreakPoint)); memset(breakpoint, 0, sizeof(WASMDebugBreakPoint));
breakpoint->addr = offset; breakpoint->addr = offset;
/* TODO: how to if more than one breakpoints are set /* TODO: how to if more than one breakpoints are set
at the same addr? */ at the same addr? */
bh_memcpy_s(&breakpoint->orignal_data, bh_memcpy_s(&breakpoint->orignal_data, (uint32)sizeof(break_instr),
(uint32)sizeof(break_instr),
module_inst->module->load_addr + offset, module_inst->module->load_addr + offset,
(uint32)sizeof(break_instr)); (uint32)sizeof(break_instr));
bh_memcpy_s(module_inst->module->load_addr + offset, bh_memcpy_s(module_inst->module->load_addr + offset,
(uint32)sizeof(break_instr), (uint32)sizeof(break_instr), break_instr,
break_instr,
(uint32)sizeof(break_instr)); (uint32)sizeof(break_instr));
bh_list_insert(&instance->break_point_list, breakpoint); bh_list_insert(&instance->break_point_list, breakpoint);
@ -796,8 +789,8 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
uint64 addr, uint64 length) uint64 length)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
@ -821,8 +814,7 @@ wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance,
WASMDebugBreakPoint *breakpoint = WASMDebugBreakPoint *breakpoint =
bh_list_first_elem(&instance->break_point_list); bh_list_first_elem(&instance->break_point_list);
while (breakpoint) { while (breakpoint) {
WASMDebugBreakPoint *next_break = WASMDebugBreakPoint *next_break = bh_list_elem_next(breakpoint);
bh_list_elem_next(breakpoint);
if (breakpoint->addr == offset) { if (breakpoint->addr == offset) {
/* TODO: how to if more than one breakpoints are set /* TODO: how to if more than one breakpoints are set
at the same addr? */ at the same addr? */
@ -901,9 +893,8 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid)
} }
bool bool
wasm_debug_instance_get_local(WASMDebugInstance *instance, wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
int frame_index, int local_index, int local_index, char buf[], int *size)
char buf[], int *size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
struct WASMInterpFrame *frame; struct WASMInterpFrame *frame;
@ -961,9 +952,8 @@ wasm_debug_instance_get_local(WASMDebugInstance *instance,
} }
bool bool
wasm_debug_instance_get_global(WASMDebugInstance *instance, wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
int frame_index, int global_index, int global_index, char buf[], int *size)
char buf[], int *size)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
struct WASMInterpFrame *frame; struct WASMInterpFrame *frame;
@ -1028,8 +1018,7 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance,
} }
uint64 uint64
wasm_debug_instance_mmap(WASMDebugInstance *instance, wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size, int map_port)
uint32 size, int map_port)
{ {
WASMExecEnv *exec_env; WASMExecEnv *exec_env;
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;

View File

@ -96,7 +96,6 @@ wasm_debug_set_engine_active(bool active);
bool bool
wasm_debug_get_engine_active(void); wasm_debug_get_engine_active(void);
uint64 uint64
wasm_debug_instance_get_pid(WASMDebugInstance *instance); wasm_debug_instance_get_pid(WASMDebugInstance *instance);
@ -104,8 +103,8 @@ uint64
wasm_debug_instance_get_tid(WASMDebugInstance *instance); wasm_debug_instance_get_tid(WASMDebugInstance *instance);
int int
wasm_debug_instance_get_tids(WASMDebugInstance *instance, wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
uint64 tids[], int len); int len);
void void
wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, uint64 tid); wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, uint64 tid);
@ -124,32 +123,32 @@ wasm_debug_instance_destroy_memregion(WASMDebugInstance *instance,
WASMDebugMemoryInfo *mem_info); WASMDebugMemoryInfo *mem_info);
bool bool
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 addr,
uint64 addr, char *buf, uint64 *size); char *buf, uint64 *size);
bool bool
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, uint64 addr,
uint64 addr, char *buf, uint64 *size); char *buf, uint64 *size);
bool bool
wasm_debug_instance_get_mem(WASMDebugInstance *instance, wasm_debug_instance_get_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
uint64 addr, char *buf, uint64 *size); uint64 *size);
bool bool
wasm_debug_instance_set_mem(WASMDebugInstance *instance, wasm_debug_instance_set_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
uint64 addr, char *buf, uint64 *size); uint64 *size);
int int
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
uint64 tid, uint64 buf[], uint64 size); uint64 buf[], uint64 size);
bool bool
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, uint64 addr,
uint64 addr, uint64 length); uint64 length);
bool bool
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
uint64 addr, uint64 length); uint64 length);
bool bool
wasm_debug_instance_continue(WASMDebugInstance *instance); wasm_debug_instance_continue(WASMDebugInstance *instance);
@ -158,21 +157,19 @@ bool
wasm_debug_instance_kill(WASMDebugInstance *instance); wasm_debug_instance_kill(WASMDebugInstance *instance);
uint64 uint64
wasm_debug_instance_wait_thread(WASMDebugInstance *instance, wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
uint64 tid, uint32 *status); uint32 *status);
bool bool
wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid); wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid);
bool bool
wasm_debug_instance_get_local(WASMDebugInstance *instance, wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
int frame_index, int local_index, int local_index, char buf[], int *size);
char buf[], int *size);
bool bool
wasm_debug_instance_get_global(WASMDebugInstance *instance, wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
int frame_index, int global_index, int global_index, char buf[], int *size);
char buf[], int *size);
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
bool bool
@ -181,8 +178,8 @@ wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
#endif #endif
uint64 uint64
wasm_debug_instance_mmap(WASMDebugInstance *instance, wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
uint32 size, int map_port); int map_port);
bool bool
wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr); wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr);

View File

@ -76,7 +76,8 @@ wasm_launch_gdbserver(char *host, int port)
ret = fcntl(listen_fd, F_SETFD, FD_CLOEXEC); ret = fcntl(listen_fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) { if (ret < 0) {
LOG_ERROR("wasm gdb server error: fcntl() failed on setting FD_CLOEXEC"); LOG_ERROR(
"wasm gdb server error: fcntl() failed on setting FD_CLOEXEC");
goto fail; goto fail;
} }

View File

@ -140,7 +140,8 @@ handle_generay_query(WASMGDBServer *server, char *payload)
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
} }
if (!strcmp(name, "Supported")) { if (!strcmp(name, "Supported")) {
sprintf(tmpbuf, "qXfer:libraries:read+;PacketSize=%x;", MAX_PACKET_SIZE); sprintf(tmpbuf, "qXfer:libraries:read+;PacketSize=%x;",
MAX_PACKET_SIZE);
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
} }
@ -163,8 +164,7 @@ handle_generay_query(WASMGDBServer *server, char *payload)
if (!strcmp(name, "HostInfo")) { if (!strcmp(name, "HostInfo")) {
// Todo: change vendor to Intel for outside tree // Todo: change vendor to Intel for outside tree
char triple[256]; char triple[256];
mem2hex("wasm32-Ant-wasi-wasm", triple, mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
strlen("wasm32-Ant-wasi-wasm"));
sprintf(tmpbuf, sprintf(tmpbuf,
"vendor:Ant;ostype:wasi;arch:wasm32;" "vendor:Ant;ostype:wasi;arch:wasm32;"
"triple:%s;endian:little;ptrsize:4;", "triple:%s;endian:little;ptrsize:4;",
@ -189,8 +189,7 @@ handle_generay_query(WASMGDBServer *server, char *payload)
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
char triple[256]; char triple[256];
// arch-vendor-os-env(format) // arch-vendor-os-env(format)
mem2hex("wasm32-Ant-wasi-wasm", triple, mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
strlen("wasm32-Ant-wasi-wasm"));
sprintf(tmpbuf, sprintf(tmpbuf,
"pid:%lx;parent-pid:%lx;vendor:Ant;ostype:wasi;arch:wasm32;" "pid:%lx;parent-pid:%lx;vendor:Ant;ostype:wasi;arch:wasm32;"
"triple:%s;endian:little;ptrsize:4;", "triple:%s;endian:little;ptrsize:4;",
@ -220,7 +219,8 @@ handle_generay_query(WASMGDBServer *server, char *payload)
char name[256]; char name[256];
mem2hex(mem_info->name, name, strlen(mem_info->name)); mem2hex(mem_info->name, name, strlen(mem_info->name));
sprintf(tmpbuf, "start:%lx;size:%lx;permissions:%s;name:%s;", sprintf(tmpbuf, "start:%lx;size:%lx;permissions:%s;name:%s;",
(uint64)mem_info->start, mem_info->size, mem_info->permisson, name); (uint64)mem_info->start, mem_info->size,
mem_info->permisson, name);
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
wasm_debug_instance_destroy_memregion( wasm_debug_instance_destroy_memregion(
(WASMDebugInstance *)server->thread->debug_instance, mem_info); (WASMDebugInstance *)server->thread->debug_instance, mem_info);
@ -228,11 +228,9 @@ handle_generay_query(WASMGDBServer *server, char *payload)
} }
if (!strcmp(name, "WasmData")) { if (!strcmp(name, "WasmData")) {
} }
if (!strcmp(name, "WasmMem")) { if (!strcmp(name, "WasmMem")) {
} }
if (!strcmp(name, "Symbol")) { if (!strcmp(name, "Symbol")) {
@ -285,7 +283,8 @@ send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
} }
// TODO: how name a wasm thread? // TODO: how name a wasm thread?
len += sprintf(tmpbuf, "T%02xthread:%lx;name:%s;", gdb_status, tid, "nobody"); len +=
sprintf(tmpbuf, "T%02xthread:%lx;name:%s;", gdb_status, tid, "nobody");
if (tids_number > 0) { if (tids_number > 0) {
len += sprintf(tmpbuf + len, "threads:"); len += sprintf(tmpbuf + len, "threads:");
while (i < tids_number) { while (i < tids_number) {
@ -423,8 +422,8 @@ handle_get_read_memory(WASMGDBServer *server, char *payload)
char *buff = wasm_runtime_malloc(mlen); char *buff = wasm_runtime_malloc(mlen);
if (buff) { if (buff) {
ret = wasm_debug_instance_get_mem( ret = wasm_debug_instance_get_mem(
(WASMDebugInstance *)server->thread->debug_instance, maddr, buff, (WASMDebugInstance *)server->thread->debug_instance, maddr,
&mlen); buff, &mlen);
if (ret) { if (ret) {
mem2hex(buff, tmpbuf, mlen); mem2hex(buff, tmpbuf, mlen);
} }
@ -451,8 +450,8 @@ handle_get_write_memory(WASMGDBServer *server, char *payload)
if (buff) { if (buff) {
hex2mem(payload, buff, act_len); hex2mem(payload, buff, act_len);
ret = wasm_debug_instance_set_mem( ret = wasm_debug_instance_set_mem(
(WASMDebugInstance *)server->thread->debug_instance, maddr, buff, (WASMDebugInstance *)server->thread->debug_instance, maddr,
&mlen); buff, &mlen);
if (ret) { if (ret) {
sprintf(tmpbuf, "%s", "OK"); sprintf(tmpbuf, "%s", "OK");
} }
@ -572,7 +571,8 @@ handle_malloc(WASMGDBServer *server, char *payload)
args++; args++;
} }
addr = wasm_debug_instance_mmap( addr = wasm_debug_instance_mmap(
(WASMDebugInstance *)server->thread->debug_instance, size, map_port); (WASMDebugInstance *)server->thread->debug_instance, size,
map_port);
if (addr) { if (addr) {
sprintf(tmpbuf, "%lx", addr); sprintf(tmpbuf, "%lx", addr);
} }

View File

@ -83,8 +83,7 @@ write_hex(WASMGDBServer *gdbserver, unsigned long hex)
} }
void void
write_packet_bytes(WASMGDBServer *gdbserver, write_packet_bytes(WASMGDBServer *gdbserver, const uint8_t *data,
const uint8_t *data,
size_t num_bytes) size_t num_bytes)
{ {
uint8_t checksum; uint8_t checksum;
@ -106,10 +105,8 @@ write_packet(WASMGDBServer *gdbserver, const char *data)
} }
void void
write_binary_packet(WASMGDBServer *gdbserver, write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
const char *pfx, const uint8_t *data, ssize_t num_bytes)
const uint8_t *data,
ssize_t num_bytes)
{ {
uint8_t *buf; uint8_t *buf;
ssize_t pfx_num_chars = strlen(pfx); ssize_t pfx_num_chars = strlen(pfx);

View File

@ -12,6 +12,7 @@
#define WAMR_PTHREAD_KEYS_MAX 32 #define WAMR_PTHREAD_KEYS_MAX 32
/* clang-format off */
#define get_module(exec_env) \ #define get_module(exec_env) \
wasm_exec_env_get_module(exec_env) wasm_exec_env_get_module(exec_env)
@ -35,10 +36,10 @@
#define addr_native_to_app(ptr) \ #define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr) wasm_runtime_addr_native_to_app(module_inst, ptr)
/* clang-format on */
extern bool extern bool
wasm_runtime_call_indirect(wasm_exec_env_t exec_env, wasm_runtime_call_indirect(wasm_exec_env_t exec_env, uint32 element_indices,
uint32 element_indices,
uint32 argc, uint32 argv[]); uint32 argc, uint32 argv[]);
enum { enum {
@ -161,8 +162,7 @@ lib_pthread_init()
if (0 != os_mutex_init(&thread_global_lock)) if (0 != os_mutex_init(&thread_global_lock))
return false; return false;
bh_list_init(&cluster_info_list); bh_list_init(&cluster_info_list);
if (!wasm_cluster_register_destroy_callback( if (!wasm_cluster_register_destroy_callback(lib_pthread_destroy_callback)) {
lib_pthread_destroy_callback)) {
os_mutex_destroy(&thread_global_lock); os_mutex_destroy(&thread_global_lock);
return false; return false;
} }
@ -199,26 +199,26 @@ static KeyData*
key_data_list_lookup(wasm_exec_env_t exec_env, int32 key) key_data_list_lookup(wasm_exec_env_t exec_env, int32 key)
{ {
ClusterInfoNode *node; ClusterInfoNode *node;
WASMCluster *cluster = WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
wasm_exec_env_get_cluster(exec_env);
if ((node = get_cluster_info(cluster))) { if ((node = get_cluster_info(cluster))) {
return (key >= 0 && key < WAMR_PTHREAD_KEYS_MAX return (key >= 0 && key < WAMR_PTHREAD_KEYS_MAX
&& node->key_data_list[key].is_created) && node->key_data_list[key].is_created)
? &(node->key_data_list[key]) : NULL; ? &(node->key_data_list[key])
: NULL;
} }
return NULL; return NULL;
} }
/* Lookup the thread key value node for a thread, /**
create a new one if failed * Lookup the thread key value node for a thread, create a new one if failed
This design will reduce the memory usage. If the thread doesn't use * This design will reduce the memory usage. If the thread doesn't use the
the local storage, it will not occupy memory space * local storage, it will not occupy memory space.
*/ */
static int32 * static int32 *
key_value_list_lookup_or_create(wasm_exec_env_t exec_env, key_value_list_lookup_or_create(wasm_exec_env_t exec_env, ClusterInfoNode *info,
ClusterInfoNode *info, int32 key) int32 key)
{ {
KeyData *key_node; KeyData *key_node;
ThreadKeyValueNode *data; ThreadKeyValueNode *data;
@ -296,9 +296,7 @@ call_key_destructor(wasm_exec_env_t exec_env)
uint32 argv[1]; uint32 argv[1];
argv[0] = value; argv[0] = value;
wasm_runtime_call_indirect(exec_env, wasm_runtime_call_indirect(exec_env, destructor_index, 1, argv);
destructor_index,
1, argv);
} }
} }
} }
@ -346,12 +344,9 @@ create_cluster_info(WASMCluster *cluster)
} }
node->cluster = cluster; node->cluster = cluster;
if (!(node->thread_info_map = if (!(node->thread_info_map = bh_hash_map_create(
bh_hash_map_create(32, true, 32, true, (HashFunc)thread_handle_hash,
(HashFunc)thread_handle_hash, (KeyEqualFunc)thread_handle_equal, NULL, thread_info_destroy))) {
(KeyEqualFunc)thread_handle_equal,
NULL,
thread_info_destroy))) {
os_mutex_destroy(&node->key_data_list_lock); os_mutex_destroy(&node->key_data_list_lock);
wasm_runtime_free(node); wasm_runtime_free(node);
return NULL; return NULL;
@ -395,13 +390,12 @@ delete_thread_info_node(ThreadInfoNode *thread_info)
{ {
ClusterInfoNode *node; ClusterInfoNode *node;
bool ret; bool ret;
WASMCluster *cluster = WASMCluster *cluster = wasm_exec_env_get_cluster(thread_info->exec_env);
wasm_exec_env_get_cluster(thread_info->exec_env);
if ((node = get_cluster_info(cluster))) { if ((node = get_cluster_info(cluster))) {
ret = bh_hash_map_remove(node->thread_info_map, ret = bh_hash_map_remove(node->thread_info_map,
(void *)(uintptr_t)thread_info->handle, (void *)(uintptr_t)thread_info->handle, NULL,
NULL, NULL); NULL);
(void)ret; (void)ret;
} }
@ -412,8 +406,7 @@ static bool
append_thread_info_node(ThreadInfoNode *thread_info) append_thread_info_node(ThreadInfoNode *thread_info)
{ {
ClusterInfoNode *node; ClusterInfoNode *node;
WASMCluster *cluster = WASMCluster *cluster = wasm_exec_env_get_cluster(thread_info->exec_env);
wasm_exec_env_get_cluster(thread_info->exec_env);
if (!(node = get_cluster_info(cluster))) { if (!(node = get_cluster_info(cluster))) {
if (!(node = create_cluster_info(cluster))) { if (!(node = create_cluster_info(cluster))) {
@ -482,9 +475,8 @@ pthread_start_routine(void *arg)
wasm_exec_env_set_thread_info(exec_env); wasm_exec_env_set_thread_info(exec_env);
argv[0] = routine_args->arg; argv[0] = routine_args->arg;
if(!wasm_runtime_call_indirect(exec_env, if (!wasm_runtime_call_indirect(exec_env, routine_args->elem_index, 1,
routine_args->elem_index, argv)) {
1, argv)) {
if (wasm_runtime_get_exception(module_inst)) if (wasm_runtime_get_exception(module_inst))
wasm_cluster_spread_exception(exec_env); wasm_cluster_spread_exception(exec_env);
} }
@ -539,15 +531,13 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
bh_assert(module); bh_assert(module);
bh_assert(module_inst); bh_assert(module_inst);
if (!(new_module_inst = if (!(new_module_inst = wasm_runtime_instantiate_internal(
wasm_runtime_instantiate_internal(module, true, 8192, 0, module, true, 8192, 0, NULL, 0)))
NULL, 0)))
return -1; return -1;
/* Set custom_data to new module instance */ /* Set custom_data to new module instance */
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
new_module_inst, new_module_inst, wasm_runtime_get_custom_data(module_inst));
wasm_runtime_get_custom_data(module_inst));
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx = get_wasi_ctx(module_inst);
@ -575,9 +565,8 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
routine_args->module_inst = new_module_inst; routine_args->module_inst = new_module_inst;
os_mutex_lock(&exec_env->wait_lock); os_mutex_lock(&exec_env->wait_lock);
ret = wasm_cluster_create_thread(exec_env, new_module_inst, ret = wasm_cluster_create_thread(
pthread_start_routine, exec_env, new_module_inst, pthread_start_routine, (void *)routine_args);
(void *)routine_args);
if (ret != 0) { if (ret != 0) {
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
goto fail; goto fail;
@ -882,8 +871,9 @@ pthread_cond_wait_wrapper(wasm_exec_env_t exec_env, uint32 *cond, uint32 *mutex)
return os_cond_wait(cond_info_node->u.cond, mutex_info_node->u.mutex); return os_cond_wait(cond_info_node->u.cond, mutex_info_node->u.mutex);
} }
/* Currently we don't support struct timespec in built-in libc, /**
so the pthread_cond_timedwait use useconds instead * Currently we don't support struct timespec in built-in libc,
* so the pthread_cond_timedwait use useconds instead
*/ */
static int32 static int32
pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond, pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond,
@ -1037,11 +1027,13 @@ pthread_key_delete_wrapper(wasm_exec_env_t exec_env, int32 key)
return 0; return 0;
} }
/* Currently the memory allocator doesn't support alloc specific aligned /**
space, we wrap posix_memalign to simply malloc memory */ * Currently the memory allocator doesn't support alloc specific aligned
* space, we wrap posix_memalign to simply malloc memory
*/
static int32 static int32
posix_memalign_wrapper(wasm_exec_env_t exec_env, posix_memalign_wrapper(wasm_exec_env_t exec_env, void **memptr, int32 align,
void **memptr, int32 align, int32 size) int32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
void *p = NULL; void *p = NULL;
@ -1053,8 +1045,10 @@ posix_memalign_wrapper(wasm_exec_env_t exec_env,
return 0; return 0;
} }
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL } { #func_name, func_name##_wrapper, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_lib_pthread[] = { static NativeSymbol native_symbols_lib_pthread[] = {
REG_NATIVE_FUNC(pthread_create, "(**ii)i"), REG_NATIVE_FUNC(pthread_create, "(**ii)i"),

View File

@ -29,9 +29,10 @@ void
wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack); wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack);
uint32 uint32
wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, uint32 size,
uint32 size, void **p_native_addr); void **p_native_addr);
/* clang-format off */
#define get_module_inst(exec_env) \ #define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env) wasm_runtime_get_module_inst(exec_env)
@ -55,6 +56,7 @@ wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr,
#define module_free(offset) \ #define module_free(offset) \
wasm_runtime_module_free(module_inst, offset) wasm_runtime_module_free(module_inst, offset)
/* clang-format on */
typedef int (*out_func_t)(int c, void *ctx); typedef int (*out_func_t)(int c, void *ctx);
@ -66,12 +68,11 @@ enum pad_type {
}; };
typedef char *_va_list; typedef char *_va_list;
#define _INTSIZEOF(n) \ #define _INTSIZEOF(n) (((uint32)sizeof(n) + 3) & (uint32)~3)
(((uint32)sizeof(n) + 3) & (uint32)~3) #define _va_arg(ap, t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define _va_arg(ap, t) \
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define CHECK_VA_ARG(ap, t) do { \ #define CHECK_VA_ARG(ap, t) \
do { \
if ((uint8 *)ap + _INTSIZEOF(t) > native_end_addr) \ if ((uint8 *)ap + _INTSIZEOF(t) > native_end_addr) \
goto fail; \ goto fail; \
} while (0) } while (0)
@ -86,10 +87,8 @@ typedef char *_va_list;
* @return N/A * @return N/A
*/ */
static void static void
_printf_hex_uint(out_func_t out, void *ctx, _printf_hex_uint(out_func_t out, void *ctx, const uint64 num, bool is_u64,
const uint64 num, bool is_u64, enum pad_type padding, int min_width)
enum pad_type padding,
int min_width)
{ {
int shift = sizeof(num) * 8; int shift = sizeof(num) * 8;
int found_largest_digit = 0; int found_largest_digit = 0;
@ -112,7 +111,8 @@ _printf_hex_uint(out_func_t out, void *ctx,
if (remaining-- <= min_width) { if (remaining-- <= min_width) {
if (padding == PAD_ZERO_BEFORE) { if (padding == PAD_ZERO_BEFORE) {
out('0', ctx); out('0', ctx);
} else if (padding == PAD_SPACE_BEFORE) { }
else if (padding == PAD_SPACE_BEFORE) {
out(' ', ctx); out(' ', ctx);
} }
} }
@ -136,10 +136,8 @@ _printf_hex_uint(out_func_t out, void *ctx,
* @return N/A * @return N/A
*/ */
static void static void
_printf_dec_uint(out_func_t out, void *ctx, _printf_dec_uint(out_func_t out, void *ctx, const uint32 num,
const uint32 num, enum pad_type padding, int min_width)
enum pad_type padding,
int min_width)
{ {
uint32 pos = 999999999; uint32 pos = 999999999;
uint32 remainder = num; uint32 remainder = num;
@ -157,7 +155,8 @@ _printf_dec_uint(out_func_t out, void *ctx,
found_largest_digit = 1; found_largest_digit = 1;
out((int)((remainder / (pos + 1)) + 48), ctx); out((int)((remainder / (pos + 1)) + 48), ctx);
digits++; digits++;
} else if (remaining <= min_width && padding < PAD_SPACE_AFTER) { }
else if (remaining <= min_width && padding < PAD_SPACE_AFTER) {
out((int)(padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx); out((int)(padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx);
digits++; digits++;
} }
@ -193,8 +192,8 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
int long_ctr = 0; int long_ctr = 0;
uint8 *native_end_addr; uint8 *native_end_addr;
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap, if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)ap, NULL,
NULL, &native_end_addr)) &native_end_addr))
goto fail; goto fail;
/* fmt has already been adjusted if needed */ /* fmt has already been adjusted if needed */
@ -235,7 +234,8 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
handle_1_to_9: handle_1_to_9:
if (min_width < 0) { if (min_width < 0) {
min_width = *fmt - '0'; min_width = *fmt - '0';
} else { }
else {
min_width = 10 * min_width + *fmt - '0'; min_width = 10 * min_width + *fmt - '0';
} }
@ -253,7 +253,8 @@ handle_1_to_9:
goto still_might_format; goto still_might_format;
case 'd': case 'd':
case 'i': { case 'i':
{
int32 d; int32 d;
if (long_ctr < 2) { if (long_ctr < 2) {
@ -279,7 +280,8 @@ handle_1_to_9:
_printf_dec_uint(out, ctx, (uint32)d, padding, min_width); _printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
break; break;
} }
case 'u': { case 'u':
{
uint32 u; uint32 u;
if (long_ctr < 2) { if (long_ctr < 2) {
@ -307,14 +309,16 @@ handle_1_to_9:
min_width = 8; min_width = 8;
/* Fall through */ /* Fall through */
case 'x': case 'x':
case 'X': { case 'X':
{
uint64 x; uint64 x;
bool is_ptr = (*fmt == 'p') ? true : false; bool is_ptr = (*fmt == 'p') ? true : false;
if (long_ctr < 2) { if (long_ctr < 2) {
CHECK_VA_ARG(ap, uint32); CHECK_VA_ARG(ap, uint32);
x = _va_arg(ap, uint32); x = _va_arg(ap, uint32);
} else { }
else {
CHECK_VA_ARG(ap, uint64); CHECK_VA_ARG(ap, uint64);
x = _va_arg(ap, uint64); x = _va_arg(ap, uint64);
} }
@ -322,7 +326,8 @@ handle_1_to_9:
break; break;
} }
case 's': { case 's':
{
char *s; char *s;
char *start; char *start;
uint32 s_offset; uint32 s_offset;
@ -348,7 +353,8 @@ handle_1_to_9:
break; break;
} }
case 'c': { case 'c':
{
int c; int c;
CHECK_VA_ARG(ap, int); CHECK_VA_ARG(ap, int);
c = _va_arg(ap, int); c = _va_arg(ap, int);
@ -356,12 +362,14 @@ handle_1_to_9:
break; break;
} }
case '%': { case '%':
{
out((int)'%', ctx); out((int)'%', ctx);
break; break;
} }
case 'f': { case 'f':
{
float64 f64; float64 f64;
char buf[16], *s; char buf[16], *s;
@ -411,7 +419,8 @@ sprintf_out(int c, struct str_context *ctx)
if (ctx->count == ctx->max - 1) { if (ctx->count == ctx->max - 1) {
ctx->str[ctx->count++] = '\0'; ctx->str[ctx->count++] = '\0';
} else { }
else {
ctx->str[ctx->count++] = (char)c; ctx->str[ctx->count++] = (char)c;
} }
@ -453,8 +462,7 @@ printf_out(int c, struct str_context *ctx)
#endif #endif
static int static int
printf_wrapper(wasm_exec_env_t exec_env, printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
const char * format, _va_list va_args)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
struct str_context ctx = { NULL, 0, 0 }; struct str_context ctx = { NULL, 0, 0 };
@ -463,15 +471,16 @@ printf_wrapper(wasm_exec_env_t exec_env,
if (!validate_native_addr(va_args, sizeof(int32))) if (!validate_native_addr(va_args, sizeof(int32)))
return 0; return 0;
if (!_vprintf_wa((out_func_t)printf_out, &ctx, format, va_args, module_inst)) if (!_vprintf_wa((out_func_t)printf_out, &ctx, format, va_args,
module_inst))
return 0; return 0;
return (int)ctx.count; return (int)ctx.count;
} }
static int static int
sprintf_wrapper(wasm_exec_env_t exec_env, sprintf_wrapper(wasm_exec_env_t exec_env, char *str, const char *format,
char *str, const char *format, _va_list va_args) _va_list va_args)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint8 *native_end_offset; uint8 *native_end_offset;
@ -481,8 +490,8 @@ sprintf_wrapper(wasm_exec_env_t exec_env,
if (!validate_native_addr(va_args, sizeof(uint32))) if (!validate_native_addr(va_args, sizeof(uint32)))
return 0; return 0;
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)str, if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)str, NULL,
NULL, &native_end_offset)) { &native_end_offset)) {
wasm_runtime_set_exception(module_inst, "out of bounds memory access"); wasm_runtime_set_exception(module_inst, "out of bounds memory access");
return false; return false;
} }
@ -491,7 +500,8 @@ sprintf_wrapper(wasm_exec_env_t exec_env,
ctx.max = (uint32)(native_end_offset - (uint8 *)str); ctx.max = (uint32)(native_end_offset - (uint8 *)str);
ctx.count = 0; ctx.count = 0;
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args, module_inst)) if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args,
module_inst))
return 0; return 0;
if (ctx.count < ctx.max) { if (ctx.count < ctx.max) {
@ -516,7 +526,8 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
ctx.max = size; ctx.max = size;
ctx.count = 0; ctx.count = 0;
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args, module_inst)) if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args,
module_inst))
return 0; return 0;
if (ctx.count < ctx.max) { if (ctx.count < ctx.max) {
@ -567,8 +578,8 @@ _strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
} }
static int32 static int32
memcmp_wrapper(wasm_exec_env_t exec_env, memcmp_wrapper(wasm_exec_env_t exec_env, const void *s1, const void *s2,
const void *s1, const void *s2, uint32 size) uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -580,8 +591,8 @@ memcmp_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
memcpy_wrapper(wasm_exec_env_t exec_env, memcpy_wrapper(wasm_exec_env_t exec_env, void *dst, const void *src,
void *dst, const void *src, uint32 size) uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst); uint32 dst_offset = addr_native_to_app(dst);
@ -598,8 +609,7 @@ memcpy_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
memmove_wrapper(wasm_exec_env_t exec_env, memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size)
void *dst, void *src, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst); uint32 dst_offset = addr_native_to_app(dst);
@ -616,8 +626,7 @@ memmove_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
memset_wrapper(wasm_exec_env_t exec_env, memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size)
void *s, int32 c, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 s_offset = addr_native_to_app(s); uint32 s_offset = addr_native_to_app(s);
@ -630,8 +639,7 @@ memset_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
strchr_wrapper(wasm_exec_env_t exec_env, strchr_wrapper(wasm_exec_env_t exec_env, const char *s, int32 c)
const char *s, int32 c)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *ret; char *ret;
@ -642,16 +650,15 @@ strchr_wrapper(wasm_exec_env_t exec_env,
} }
static int32 static int32
strcmp_wrapper(wasm_exec_env_t exec_env, strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2)
const char *s1, const char *s2)
{ {
/* s1 and s2 have been checked by runtime */ /* s1 and s2 have been checked by runtime */
return strcmp(s1, s2); return strcmp(s1, s2);
} }
static int32 static int32
strncmp_wrapper(wasm_exec_env_t exec_env, strncmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
const char *s1, const char *s2, uint32 size) uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -681,8 +688,8 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
} }
static uint32 static uint32
strncpy_wrapper(wasm_exec_env_t exec_env, strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
char *dst, const char *src, uint32 size) uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -767,8 +774,8 @@ exit_wrapper(wasm_exec_env_t exec_env, int32 status)
} }
static int32 static int32
strtol_wrapper(wasm_exec_env_t exec_env, strtol_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
const char *nptr, char **endptr, int32 base) int32 base)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
int32 num = 0; int32 num = 0;
@ -784,8 +791,8 @@ strtol_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
strtoul_wrapper(wasm_exec_env_t exec_env, strtoul_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
const char *nptr, char **endptr, int32 base) int32 base)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 num = 0; uint32 num = 0;
@ -801,8 +808,7 @@ strtoul_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
memchr_wrapper(wasm_exec_env_t exec_env, memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n)
const void *s, int32 c, uint32 n)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
void *res; void *res;
@ -815,32 +821,29 @@ memchr_wrapper(wasm_exec_env_t exec_env,
} }
static int32 static int32
strncasecmp_wrapper(wasm_exec_env_t exec_env, strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
const char *s1, const char *s2, uint32 n) uint32 n)
{ {
/* s1 and s2 have been checked by runtime */ /* s1 and s2 have been checked by runtime */
return strncasecmp(s1, s2, n); return strncasecmp(s1, s2, n);
} }
static uint32 static uint32
strspn_wrapper(wasm_exec_env_t exec_env, strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
const char *s, const char *accept)
{ {
/* s and accept have been checked by runtime */ /* s and accept have been checked by runtime */
return (uint32)strspn(s, accept); return (uint32)strspn(s, accept);
} }
static uint32 static uint32
strcspn_wrapper(wasm_exec_env_t exec_env, strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject)
const char *s, const char *reject)
{ {
/* s and reject have been checked by runtime */ /* s and reject have been checked by runtime */
return (uint32)strcspn(s, reject); return (uint32)strcspn(s, reject);
} }
static uint32 static uint32
strstr_wrapper(wasm_exec_env_t exec_env, strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
const char *s, const char *find)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* s and find have been checked by runtime */ /* s and find have been checked by runtime */
@ -925,24 +928,19 @@ getTempRet0_wrapper(wasm_exec_env_t exec_env)
static uint32 static uint32
llvm_bswap_i16_wrapper(wasm_exec_env_t exec_env, uint32 data) llvm_bswap_i16_wrapper(wasm_exec_env_t exec_env, uint32 data)
{ {
return (data & 0xFFFF0000) return (data & 0xFFFF0000) | ((data & 0xFF) << 8) | ((data & 0xFF00) >> 8);
| ((data & 0xFF) << 8)
| ((data & 0xFF00) >> 8);
} }
static uint32 static uint32
llvm_bswap_i32_wrapper(wasm_exec_env_t exec_env, uint32 data) llvm_bswap_i32_wrapper(wasm_exec_env_t exec_env, uint32 data)
{ {
return ((data & 0xFF) << 24) return ((data & 0xFF) << 24) | ((data & 0xFF00) << 8)
| ((data & 0xFF00) << 8) | ((data & 0xFF0000) >> 8) | ((data & 0xFF000000) >> 24);
| ((data & 0xFF0000) >> 8)
| ((data & 0xFF000000) >> 24);
} }
static uint32 static uint32
bitshift64Lshr_wrapper(wasm_exec_env_t exec_env, bitshift64Lshr_wrapper(wasm_exec_env_t exec_env, uint32 uint64_part0,
uint32 uint64_part0, uint32 uint64_part1, uint32 uint64_part1, uint32 bits)
uint32 bits)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
union { union {
@ -960,9 +958,8 @@ bitshift64Lshr_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
bitshift64Shl_wrapper(wasm_exec_env_t exec_env, bitshift64Shl_wrapper(wasm_exec_env_t exec_env, uint32 int64_part0,
uint32 int64_part0, uint32 int64_part1, uint32 int64_part1, uint32 bits)
uint32 bits)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
union { union {
@ -996,8 +993,8 @@ llvm_stacksave_wrapper(wasm_exec_env_t exec_env)
} }
static uint32 static uint32
emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env, emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env, void *dst,
void *dst, const void *src, uint32 size) const void *src, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst); uint32 dst_offset = addr_native_to_app(dst);
@ -1038,8 +1035,7 @@ nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code)
} }
static uint32 static uint32
__cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
uint32 thrown_size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 exception = module_malloc(thrown_size, NULL); uint32 exception = module_malloc(thrown_size, NULL);
@ -1050,16 +1046,12 @@ __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env,
} }
static void static void
__cxa_begin_catch_wrapper(wasm_exec_env_t exec_env, __cxa_begin_catch_wrapper(wasm_exec_env_t exec_env, void *exception_object)
void *exception_object) {}
{
}
static void static void
__cxa_throw_wrapper(wasm_exec_env_t exec_env, __cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
void *thrown_exception, void *tinfo, uint32 table_elem_idx)
void *tinfo,
uint32 table_elem_idx)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
char buf[32]; char buf[32];
@ -1074,8 +1066,8 @@ struct timespec_app {
}; };
static uint32 static uint32
clock_gettime_wrapper(wasm_exec_env_t exec_env, clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
uint32 clk_id, struct timespec_app *ts_app) struct timespec_app *ts_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint64 time; uint64 time;
@ -1103,7 +1095,6 @@ static void
print_wrapper(wasm_exec_env_t exec_env) print_wrapper(wasm_exec_env_t exec_env)
{ {
os_printf("in specttest.print()\n"); os_printf("in specttest.print()\n");
} }
static void static void
@ -1138,7 +1129,9 @@ print_f64_wrapper(wasm_exec_env_t exec_env, double f64)
#endif /* WASM_ENABLE_SPEC_TEST */ #endif /* WASM_ENABLE_SPEC_TEST */
#define REG_NATIVE_FUNC(func_name, signature) \ #define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL } { \
#func_name, func_name##_wrapper, signature, NULL \
}
static NativeSymbol native_symbols_libc_builtin[] = { static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(printf, "($*)i"), REG_NATIVE_FUNC(printf, "($*)i"),
@ -1281,4 +1274,3 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
return false; return false;
} }

View File

@ -11,6 +11,7 @@
#include "sys/syscall.h" #include "sys/syscall.h"
#endif #endif
/* clang-format off */
#define get_module_inst(exec_env) \ #define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env) wasm_runtime_get_module_inst(exec_env)
@ -34,15 +35,15 @@
#define module_free(offset) \ #define module_free(offset) \
wasm_runtime_module_free(module_inst, offset) wasm_runtime_module_free(module_inst, offset)
/* clang-format on */
extern bool extern bool
wasm_runtime_call_indirect(wasm_exec_env_t exec_env, wasm_runtime_call_indirect(wasm_exec_env_t exec_env, uint32 element_idx,
uint32 element_idx,
uint32 argc, uint32 argv[]); uint32 argc, uint32 argv[]);
static void static void
invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
int arg0, int arg1, int arg2, int arg3) int arg1, int arg2, int arg3)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -56,8 +57,8 @@ invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
} }
static void static void
invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
int arg0, int arg1, int arg2) int arg1, int arg2)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -70,8 +71,8 @@ invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
} }
static void static void
invoke_vii_wrapper(wasm_exec_env_t exec_env, invoke_vii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
uint32 elem_idx, int arg0, int arg1) int arg1)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -83,8 +84,7 @@ invoke_vii_wrapper(wasm_exec_env_t exec_env,
} }
static void static void
invoke_vi_wrapper(wasm_exec_env_t exec_env, invoke_vi_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0)
uint32 elem_idx, int arg0)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -95,8 +95,8 @@ invoke_vi_wrapper(wasm_exec_env_t exec_env,
} }
static int static int
invoke_iii_wrapper(wasm_exec_env_t exec_env, invoke_iii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
uint32 elem_idx, int arg0, int arg1) int arg1)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -108,8 +108,7 @@ invoke_iii_wrapper(wasm_exec_env_t exec_env,
} }
static int static int
invoke_ii_wrapper(wasm_exec_env_t exec_env, invoke_ii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0)
uint32 elem_idx, int arg0)
{ {
uint32 argv[4]; uint32 argv[4];
bool ret; bool ret;
@ -144,8 +143,8 @@ struct stat_emcc {
}; };
static int static int
open_wrapper(wasm_exec_env_t exec_env, const char *pathname, open_wrapper(wasm_exec_env_t exec_env, const char *pathname, int flags,
int flags, int mode) int mode)
{ {
if (pathname == NULL) if (pathname == NULL)
return -1; return -1;
@ -153,8 +152,7 @@ open_wrapper(wasm_exec_env_t exec_env, const char *pathname,
} }
static int static int
__sys_read_wrapper(wasm_exec_env_t exec_env, __sys_read_wrapper(wasm_exec_env_t exec_env, int fd, void *buf, uint32 count)
int fd, void *buf, uint32 count)
{ {
return read(fd, buf, count); return read(fd, buf, count);
} }
@ -183,8 +181,7 @@ statbuf_native2app(const struct stat *statbuf_native,
} }
static int static int
__sys_stat64_wrapper(wasm_exec_env_t exec_env, __sys_stat64_wrapper(wasm_exec_env_t exec_env, const char *pathname,
const char *pathname,
struct stat_emcc *statbuf_app) struct stat_emcc *statbuf_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -204,8 +201,8 @@ __sys_stat64_wrapper(wasm_exec_env_t exec_env,
} }
static int static int
__sys_fstat64_wrapper(wasm_exec_env_t exec_env, __sys_fstat64_wrapper(wasm_exec_env_t exec_env, int fd,
int fd, struct stat_emcc *statbuf_app) struct stat_emcc *statbuf_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
int ret; int ret;
@ -224,9 +221,8 @@ __sys_fstat64_wrapper(wasm_exec_env_t exec_env,
} }
static int static int
mmap_wrapper(wasm_exec_env_t exec_env, mmap_wrapper(wasm_exec_env_t exec_env, void *addr, int length, int prot,
void *addr, int length, int prot, int flags, int flags, int fd, int64 offset)
int fd, int64 offset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 buf_offset; uint32 buf_offset;
@ -275,16 +271,14 @@ getentropy_wrapper(wasm_exec_env_t exec_env, void *buffer, uint32 length)
} }
static int static int
setjmp_wrapper(wasm_exec_env_t exec_env, setjmp_wrapper(wasm_exec_env_t exec_env, void *jmp_buf)
void *jmp_buf)
{ {
os_printf("setjmp() called\n"); os_printf("setjmp() called\n");
return 0; return 0;
} }
static void static void
longjmp_wrapper(wasm_exec_env_t exec_env, longjmp_wrapper(wasm_exec_env_t exec_env, void *jmp_buf, int val)
void *jmp_buf, int val)
{ {
os_printf("longjmp() called\n"); os_printf("longjmp() called\n");
} }
@ -305,9 +299,7 @@ get_free_file_slot()
} }
static int static int
fopen_wrapper(wasm_exec_env_t exec_env, fopen_wrapper(wasm_exec_env_t exec_env, const char *pathname, const char *mode)
const char *pathname,
const char *mode)
{ {
FILE *file; FILE *file;
int file_id; int file_id;
@ -327,8 +319,8 @@ fopen_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
fread_wrapper(wasm_exec_env_t exec_env, fread_wrapper(wasm_exec_env_t exec_env, void *ptr, uint32 size, uint32 nmemb,
void *ptr, uint32 size, uint32 nmemb, int file_id) int file_id)
{ {
FILE *file; FILE *file;
@ -343,8 +335,7 @@ fread_wrapper(wasm_exec_env_t exec_env,
} }
static int static int
fseeko_wrapper(wasm_exec_env_t exec_env, fseeko_wrapper(wasm_exec_env_t exec_env, int file_id, int64 offset, int whence)
int file_id, int64 offset, int whence)
{ {
FILE *file; FILE *file;
@ -359,9 +350,8 @@ fseeko_wrapper(wasm_exec_env_t exec_env,
} }
static uint32 static uint32
emcc_fwrite_wrapper(wasm_exec_env_t exec_env, emcc_fwrite_wrapper(wasm_exec_env_t exec_env, const void *ptr, uint32 size,
const void *ptr, uint32 size, uint32 nmemb, uint32 nmemb, int file_id)
int file_id)
{ {
FILE *file; FILE *file;
@ -403,8 +393,7 @@ fclose_wrapper(wasm_exec_env_t exec_env, int file_id)
} }
static int static int
__sys_mkdir_wrapper(wasm_exec_env_t exec_env, __sys_mkdir_wrapper(wasm_exec_env_t exec_env, const char *pathname, int mode)
const char *pathname, int mode)
{ {
if (!pathname) if (!pathname)
return -1; return -1;
@ -522,8 +511,10 @@ emscripten_thread_sleep_wrapper(wasm_exec_env_t exec_env, double timeout_ms)
#endif /* end of BH_PLATFORM_LINUX_SGX */ #endif /* end of BH_PLATFORM_LINUX_SGX */
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL } { #func_name, func_name##_wrapper, signature, NULL }
/* clang-format off */
static NativeSymbol native_symbols_libc_emcc[] = { static NativeSymbol native_symbols_libc_emcc[] = {
REG_NATIVE_FUNC(invoke_viiii, "(iiiii)"), REG_NATIVE_FUNC(invoke_viiii, "(iiiii)"),

View File

@ -7,6 +7,7 @@
#include "bh_platform.h" #include "bh_platform.h"
#include "wasm_export.h" #include "wasm_export.h"
/* clang-format off */
#define get_module_inst(exec_env) \ #define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env) wasm_runtime_get_module_inst(exec_env)
@ -30,6 +31,7 @@
#define module_free(offset) \ #define module_free(offset) \
wasm_runtime_module_free(module_inst, offset) wasm_runtime_module_free(module_inst, offset)
/* clang-format on */
#define wasi_errno_t uvwasi_errno_t #define wasi_errno_t uvwasi_errno_t
#define wasi_fd_t uvwasi_fd_t #define wasi_fd_t uvwasi_fd_t
@ -117,8 +119,8 @@ wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
} }
static wasi_errno_t static wasi_errno_t
wasi_args_sizes_get(wasm_exec_env_t exec_env, wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
uint32 *argc_app, uint32 *argv_buf_size_app) uint32 *argv_buf_size_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -132,7 +134,6 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(argv_buf_size_app, sizeof(uint32))) || !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size); err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
if (err) if (err)
return err; return err;
@ -143,8 +144,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_clock_res_get(wasm_exec_env_t exec_env, wasi_clock_res_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
wasi_clockid_t clock_id,
wasi_timestamp_t *resolution) wasi_timestamp_t *resolution)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -157,10 +157,8 @@ wasi_clock_res_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_clock_time_get(wasm_exec_env_t exec_env, wasi_clock_time_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
wasi_clockid_t clock_id, wasi_timestamp_t precision, wasi_timestamp_t *time)
wasi_timestamp_t precision,
wasi_timestamp_t *time)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -172,8 +170,8 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_environ_get(wasm_exec_env_t exec_env, wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
uint32 *environ_offsets, char *environ_buf) char *environ_buf)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -217,8 +215,8 @@ wasi_environ_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_environ_sizes_get(wasm_exec_env_t exec_env, wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
uint32 *environ_count_app, uint32 *environ_buf_size_app) uint32 *environ_buf_size_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -242,8 +240,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_prestat_app_t *prestat_app) wasi_prestat_app_t *prestat_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -266,8 +264,8 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
wasi_fd_t fd, char *path, uint32 path_len) uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -303,9 +301,8 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
wasi_fd_t fd, iovec_app_t *iovec_app, uint32 iovs_len, uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
wasi_filesize_t offset, uint32 *nread_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -339,8 +336,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = uvwasi_fd_pread(uvwasi, fd, iovec_begin, err = uvwasi_fd_pread(uvwasi, fd, iovec_begin, iovs_len, offset, &nread);
iovs_len, offset, &nread);
if (err) if (err)
goto fail; goto fail;
@ -355,8 +351,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len, const iovec_app_t *iovec_app, uint32 iovs_len,
wasi_filesize_t offset, uint32 *nwritten_app) wasi_filesize_t offset, uint32 *nwritten_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -391,8 +387,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
err = uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin, err =
iovs_len, offset, &nwritten); uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin, iovs_len, offset, &nwritten);
if (err) if (err)
goto fail; goto fail;
@ -407,9 +403,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len, const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
uint32 *nread_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -443,8 +438,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = uvwasi_fd_read(uvwasi, fd, err = uvwasi_fd_read(uvwasi, fd, iovec_begin, iovs_len, &nread);
iovec_begin, iovs_len, &nread);
if (err) if (err)
goto fail; goto fail;
@ -471,9 +465,8 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
wasi_fd_t fd, wasi_filedelta_t offset, wasi_whence_t whence, wasi_whence_t whence, wasi_filesize_t *newoffset)
wasi_filesize_t *newoffset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -488,8 +481,7 @@ wasi_fd_seek(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
wasi_fd_t fd, wasi_filesize_t *newoffset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -504,8 +496,8 @@ wasi_fd_tell(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_fdstat_t *fdstat_app) wasi_fdstat_t *fdstat_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -527,8 +519,8 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_fdflags_t flags) wasi_fdflags_t flags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -540,8 +532,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd,
wasi_rights_t fs_rights_base, wasi_rights_t fs_rights_base,
wasi_rights_t fs_rights_inheriting) wasi_rights_t fs_rights_inheriting)
{ {
@ -551,8 +542,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_fd_fdstat_set_rights(uvwasi, fd, return uvwasi_fd_fdstat_set_rights(uvwasi, fd, fs_rights_base,
fs_rights_base, fs_rights_inheriting); fs_rights_inheriting);
} }
static wasi_errno_t static wasi_errno_t
@ -643,11 +634,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
wasi_fd_t fd, wasi_filesize_t len, wasi_advice_t advice)
wasi_filesize_t offset,
wasi_filesize_t len,
wasi_advice_t advice)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -659,9 +647,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
wasi_fd_t fd,
wasi_filesize_t offset,
wasi_filesize_t len) wasi_filesize_t len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -674,8 +660,8 @@ wasi_fd_allocate(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const char *path, uint32 path_len) const char *path, uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -687,12 +673,10 @@ wasi_path_create_directory(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_link(wasm_exec_env_t exec_env, wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t old_fd, wasi_lookupflags_t old_flags, const char *old_path,
wasi_lookupflags_t old_flags, uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
const char *old_path, uint32 old_path_len, uint32 new_path_len)
wasi_fd_t new_fd,
const char *new_path, uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -700,20 +684,15 @@ wasi_path_link(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_path_link(uvwasi, return uvwasi_path_link(uvwasi, old_fd, old_flags, old_path, old_path_len,
old_fd, old_flags, old_path, old_path_len,
new_fd, new_path, new_path_len); new_fd, new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_open(wasm_exec_env_t exec_env, wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
wasi_fd_t dirfd, wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
wasi_lookupflags_t dirflags, wasi_oflags_t oflags, wasi_rights_t fs_rights_base,
const char *path, uint32 path_len, wasi_rights_t fs_rights_inheriting, wasi_fdflags_t fs_flags,
wasi_oflags_t oflags,
wasi_rights_t fs_rights_base,
wasi_rights_t fs_rights_inheriting,
wasi_fdflags_t fs_flags,
wasi_fd_t *fd_app) wasi_fd_t *fd_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -727,24 +706,39 @@ wasi_path_open(wasm_exec_env_t exec_env,
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = uvwasi_path_open(uvwasi, err = uvwasi_path_open(uvwasi, dirfd, dirflags, path, path_len, oflags,
dirfd, dirflags, fs_rights_base, fs_rights_inheriting, fs_flags, &fd);
path, path_len,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
&fd);
*fd_app = fd; *fd_app = fd;
return err; return err;
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
wasi_fd_t fd, uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
void *buf, uint32 buf_len, {
wasi_dircookie_t cookie, wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
uvwasi_size_t bufused;
wasi_errno_t err;
if (!uvwasi)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = uvwasi_fd_readdir(uvwasi, fd, buf, buf_len, cookie, &bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
return 0;
}
static wasi_errno_t
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
uint32 path_len, char *buf, uint32 buf_len,
uint32 *bufused_app) uint32 *bufused_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -758,8 +752,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = uvwasi_fd_readdir(uvwasi, fd, err = uvwasi_path_readlink(uvwasi, fd, path, path_len, buf, buf_len,
buf, buf_len, cookie, &bufused); &bufused);
if (err) if (err)
return err; return err;
@ -768,37 +762,9 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t fd, const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
const char *path, uint32 path_len, const char *new_path, uint32 new_path_len)
char *buf, uint32 buf_len,
uint32 *bufused_app)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
uvwasi_size_t bufused;
wasi_errno_t err;
if (!uvwasi)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = uvwasi_path_readlink(uvwasi, fd,
path, path_len,
buf, buf_len, &bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
return 0;
}
static wasi_errno_t
wasi_path_rename(wasm_exec_env_t exec_env,
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len,
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -806,14 +772,13 @@ wasi_path_rename(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_path_rename(uvwasi, return uvwasi_path_rename(uvwasi, old_fd, old_path, old_path_len, new_fd,
old_fd, old_path, old_path_len, new_path, new_path_len);
new_fd, new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_filestat_t *filestat) wasi_filestat_t *filestat)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -828,10 +793,8 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_timestamp_t st_atim, wasi_timestamp_t st_mtim,
wasi_timestamp_t st_atim,
wasi_timestamp_t st_mtim,
wasi_fstflags_t fstflags) wasi_fstflags_t fstflags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -840,13 +803,11 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_fd_filestat_set_times(uvwasi, fd, return uvwasi_fd_filestat_set_times(uvwasi, fd, st_atim, st_mtim, fstflags);
st_atim, st_mtim, fstflags);
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd,
wasi_filesize_t st_size) wasi_filesize_t st_size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -859,11 +820,9 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_lookupflags_t flags, const char *path,
wasi_lookupflags_t flags, uint32 path_len, wasi_filestat_t *filestat)
const char *path, uint32 path_len,
wasi_filestat_t *filestat)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -874,18 +833,15 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_path_filestat_get(uvwasi, fd, return uvwasi_path_filestat_get(uvwasi, fd, flags, path, path_len,
flags, path, path_len, filestat); filestat);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_lookupflags_t flags, const char *path,
wasi_lookupflags_t flags, uint32 path_len, wasi_timestamp_t st_atim,
const char *path, uint32 path_len, wasi_timestamp_t st_mtim, wasi_fstflags_t fstflags)
wasi_timestamp_t st_atim,
wasi_timestamp_t st_mtim,
wasi_fstflags_t fstflags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -893,15 +849,14 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_path_filestat_set_times(uvwasi, fd, return uvwasi_path_filestat_set_times(uvwasi, fd, flags, path, path_len,
flags, path, path_len,
st_atim, st_mtim, fstflags); st_atim, st_mtim, fstflags);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_symlink(wasm_exec_env_t exec_env, wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
const char *old_path, uint32 old_path_len, uint32 old_path_len, wasi_fd_t fd, const char *new_path,
wasi_fd_t fd, const char *new_path, uint32 new_path_len) uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -909,14 +864,13 @@ wasi_path_symlink(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return uvwasi_path_symlink(uvwasi, return uvwasi_path_symlink(uvwasi, old_path, old_path_len, fd, new_path,
old_path, old_path_len, fd, new_path_len);
new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
wasi_fd_t fd, const char *path, uint32 path_len) uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -928,8 +882,8 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const char *path, uint32 path_len) const char *path, uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -941,9 +895,8 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_poll_oneoff(wasm_exec_env_t exec_env, wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
const wasi_subscription_t *in, wasi_event_t *out, wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
uint32 nsubscriptions, uint32 *nevents_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -958,8 +911,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
|| !validate_native_addr(nevents_app, sizeof(uint32))) || !validate_native_addr(nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = uvwasi_poll_oneoff(uvwasi, in, out, err = uvwasi_poll_oneoff(uvwasi, in, out, nsubscriptions, &nevents);
nsubscriptions, &nevents);
if (err) if (err)
return err; return err;
@ -997,12 +949,9 @@ wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
wasi_fd_t sock, uint32 ri_data_len, wasi_riflags_t ri_flags,
iovec_app_t *ri_data, uint32 ri_data_len, uint32 *ro_datalen_app, wasi_roflags_t *ro_flags)
wasi_riflags_t ri_flags,
uint32 *ro_datalen_app,
wasi_roflags_t *ro_flags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -1037,10 +986,8 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
iovec->buf_len = ri_data->buf_len; iovec->buf_len = ri_data->buf_len;
} }
err = uvwasi_sock_recv(uvwasi, sock, err = uvwasi_sock_recv(uvwasi, sock, iovec_begin, ri_data_len, ri_flags,
iovec_begin, ri_data_len, &ro_datalen, ro_flags);
ri_flags, &ro_datalen,
ro_flags);
if (err) if (err)
goto fail; goto fail;
@ -1055,11 +1002,9 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_send(wasm_exec_env_t exec_env, wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
wasi_fd_t sock,
const iovec_app_t *si_data, uint32 si_data_len, const iovec_app_t *si_data, uint32 si_data_len,
wasi_siflags_t si_flags, wasi_siflags_t si_flags, uint32 *so_datalen_app)
uint32 *so_datalen_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -1093,9 +1038,8 @@ wasi_sock_send(wasm_exec_env_t exec_env,
ciovec->buf_len = si_data->buf_len; ciovec->buf_len = si_data->buf_len;
} }
err = uvwasi_sock_send(uvwasi, sock, err = uvwasi_sock_send(uvwasi, sock, ciovec_begin, si_data_len, si_flags,
ciovec_begin, si_data_len, &so_datalen);
si_flags, &so_datalen);
if (err) if (err)
goto fail; goto fail;
@ -1110,8 +1054,7 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
wasi_fd_t sock, wasi_sdflags_t how)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -1131,8 +1074,10 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
return uvwasi_sched_yield(uvwasi); return uvwasi_sched_yield(uvwasi);
} }
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, wasi_##func_name, signature, NULL } { #func_name, wasi_##func_name, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = { static NativeSymbol native_symbols_libc_wasi[] = {
REG_NATIVE_FUNC(args_get, "(**)i"), REG_NATIVE_FUNC(args_get, "(**)i"),
@ -1188,4 +1133,3 @@ get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis)
*p_libc_wasi_apis = native_symbols_libc_wasi; *p_libc_wasi_apis = native_symbols_libc_wasi;
return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol); return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
} }

View File

@ -10,6 +10,7 @@
void void
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception); wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
/* clang-format off */
#define get_module_inst(exec_env) \ #define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env) wasm_runtime_get_module_inst(exec_env)
@ -33,6 +34,7 @@ wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
#define module_free(offset) \ #define module_free(offset) \
wasm_runtime_module_free(module_inst, offset) wasm_runtime_module_free(module_inst, offset)
/* clang-format on */
typedef struct wasi_prestat_app { typedef struct wasi_prestat_app {
wasi_preopentype_t pr_type; wasi_preopentype_t pr_type;
@ -58,8 +60,7 @@ wasi_ctx_t
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst); wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
static inline struct fd_table * static inline struct fd_table *
wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
wasi_ctx_t wasi_ctx)
{ {
if (!wasi_ctx) if (!wasi_ctx)
return NULL; return NULL;
@ -67,8 +68,7 @@ wasi_ctx_get_curfds(wasm_module_inst_t module_inst,
} }
static inline struct argv_environ_values * static inline struct argv_environ_values *
wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst, wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
wasi_ctx_t wasi_ctx)
{ {
if (!wasi_ctx) if (!wasi_ctx)
return NULL; return NULL;
@ -76,8 +76,7 @@ wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst,
} }
static inline struct fd_prestats * static inline struct fd_prestats *
wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
wasi_ctx_t wasi_ctx)
{ {
if (!wasi_ctx) if (!wasi_ctx)
return NULL; return NULL;
@ -130,8 +129,8 @@ wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
} }
static wasi_errno_t static wasi_errno_t
wasi_args_sizes_get(wasm_exec_env_t exec_env, wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
uint32 *argc_app, uint32 *argv_buf_size_app) uint32 *argv_buf_size_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -148,8 +147,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
argv_environ = wasi_ctx->argv_environ; argv_environ = wasi_ctx->argv_environ;
err = wasmtime_ssp_args_sizes_get(argv_environ, err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size);
&argc, &argv_buf_size);
if (err) if (err)
return err; return err;
@ -186,8 +184,8 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_environ_get(wasm_exec_env_t exec_env, wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
uint32 *environ_offsets, char *environ_buf) char *environ_buf)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -201,8 +199,8 @@ wasi_environ_get(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_sizes_get(argv_environ, err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count,
&environ_count, &environ_buf_size); &environ_buf_size);
if (err) if (err)
return err; return err;
@ -234,8 +232,8 @@ wasi_environ_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_environ_sizes_get(wasm_exec_env_t exec_env, wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
uint32 *environ_count_app, uint32 *environ_buf_size_app) uint32 *environ_buf_size_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -251,8 +249,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(environ_buf_size_app, sizeof(uint32))) || !validate_native_addr(environ_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_sizes_get(argv_environ, err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count,
&environ_count, &environ_buf_size); &environ_buf_size);
if (err) if (err)
return err; return err;
@ -263,8 +261,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_prestat_app_t *prestat_app) wasi_prestat_app_t *prestat_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -288,8 +286,8 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
wasi_fd_t fd, char *path, uint32 path_len) uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -298,8 +296,7 @@ wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_prestat_dir_name(prestats, return wasmtime_ssp_fd_prestat_dir_name(prestats, fd, path, path_len);
fd, path, path_len);
} }
static wasi_errno_t static wasi_errno_t
@ -330,9 +327,8 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
wasi_fd_t fd, iovec_app_t *iovec_app, uint32 iovs_len, uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
wasi_filesize_t offset, uint32 *nread_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -368,8 +364,8 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset,
iovs_len, offset, &nread); &nread);
if (err) if (err)
goto fail; goto fail;
@ -384,8 +380,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len, const iovec_app_t *iovec_app, uint32 iovs_len,
wasi_filesize_t offset, uint32 *nwritten_app) wasi_filesize_t offset, uint32 *nwritten_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -422,8 +418,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset,
iovs_len, offset, &nwritten); &nwritten);
if (err) if (err)
goto fail; goto fail;
@ -438,9 +434,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len, const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
uint32 *nread_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -476,8 +471,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_read(curfds, fd, err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread);
iovec_begin, iovs_len, &nread);
if (err) if (err)
goto fail; goto fail;
@ -506,9 +500,8 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
wasi_fd_t fd, wasi_filedelta_t offset, wasi_whence_t whence, wasi_whence_t whence, wasi_filesize_t *newoffset)
wasi_filesize_t *newoffset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -524,8 +517,7 @@ wasi_fd_seek(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
wasi_fd_t fd, wasi_filesize_t *newoffset)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -541,8 +533,8 @@ wasi_fd_tell(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_fdstat_t *fdstat_app) wasi_fdstat_t *fdstat_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -565,8 +557,8 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_fdflags_t flags) wasi_fdflags_t flags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -579,8 +571,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd,
wasi_rights_t fs_rights_base, wasi_rights_t fs_rights_base,
wasi_rights_t fs_rights_inheriting) wasi_rights_t fs_rights_inheriting)
{ {
@ -591,8 +582,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base,
fs_rights_base, fs_rights_inheriting); fs_rights_inheriting);
} }
static wasi_errno_t static wasi_errno_t
@ -647,8 +638,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_write(curfds, fd, err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten);
ciovec_begin, iovs_len, &nwritten);
if (err) if (err)
goto fail; goto fail;
@ -663,11 +653,8 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
wasi_fd_t fd, wasi_filesize_t len, wasi_advice_t advice)
wasi_filesize_t offset,
wasi_filesize_t len,
wasi_advice_t advice)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -680,9 +667,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
wasi_fd_t fd,
wasi_filesize_t offset,
wasi_filesize_t len) wasi_filesize_t len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -696,8 +681,8 @@ wasi_fd_allocate(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const char *path, uint32 path_len) const char *path, uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -706,17 +691,14 @@ wasi_path_create_directory(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_create_directory(curfds, fd, return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len);
path, path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_link(wasm_exec_env_t exec_env, wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t old_fd, wasi_lookupflags_t old_flags, const char *old_path,
wasi_lookupflags_t old_flags, uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
const char *old_path, uint32 old_path_len, uint32 new_path_len)
wasi_fd_t new_fd,
const char *new_path, uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -726,20 +708,15 @@ wasi_path_link(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_link(curfds, prestats, return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path,
old_fd, old_flags, old_path, old_path_len, old_path_len, new_fd, new_path, new_path_len);
new_fd, new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_open(wasm_exec_env_t exec_env, wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
wasi_fd_t dirfd, wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
wasi_lookupflags_t dirflags, wasi_oflags_t oflags, wasi_rights_t fs_rights_base,
const char *path, uint32 path_len, wasi_rights_t fs_rights_inheriting, wasi_fdflags_t fs_flags,
wasi_oflags_t oflags,
wasi_rights_t fs_rights_base,
wasi_rights_t fs_rights_inheriting,
wasi_fdflags_t fs_flags,
wasi_fd_t *fd_app) wasi_fd_t *fd_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -754,24 +731,41 @@ wasi_path_open(wasm_exec_env_t exec_env,
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(curfds, err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len,
dirfd, dirflags, oflags, fs_rights_base, fs_rights_inheriting,
path, path_len, fs_flags, &fd);
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
&fd);
*fd_app = fd; *fd_app = fd;
return err; return err;
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
wasi_fd_t fd, uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
void *buf, uint32 buf_len, {
wasi_dircookie_t cookie, wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
size_t bufused;
wasi_errno_t err;
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
return 0;
}
static wasi_errno_t
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
uint32 path_len, char *buf, uint32 buf_len,
uint32 *bufused_app) uint32 *bufused_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -786,8 +780,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(curfds, fd, err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len,
buf, buf_len, cookie, &bufused); &bufused);
if (err) if (err)
return err; return err;
@ -796,38 +790,9 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t fd, const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
const char *path, uint32 path_len, const char *new_path, uint32 new_path_len)
char *buf, uint32 buf_len,
uint32 *bufused_app)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
size_t bufused;
wasi_errno_t err;
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(curfds, fd,
path, path_len,
buf, buf_len, &bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
return 0;
}
static wasi_errno_t
wasi_path_rename(wasm_exec_env_t exec_env,
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len,
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -836,14 +801,13 @@ wasi_path_rename(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_rename(curfds, return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len,
old_fd, old_path, old_path_len,
new_fd, new_path, new_path_len); new_fd, new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_filestat_t *filestat) wasi_filestat_t *filestat)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -859,10 +823,8 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_timestamp_t st_atim, wasi_timestamp_t st_mtim,
wasi_timestamp_t st_atim,
wasi_timestamp_t st_mtim,
wasi_fstflags_t fstflags) wasi_fstflags_t fstflags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -872,13 +834,12 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_set_times(curfds, fd, return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim,
st_atim, st_mtim, fstflags); fstflags);
} }
static wasi_errno_t static wasi_errno_t
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd,
wasi_filesize_t st_size) wasi_filesize_t st_size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
@ -892,11 +853,9 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_lookupflags_t flags, const char *path,
wasi_lookupflags_t flags, uint32 path_len, wasi_filestat_t *filestat)
const char *path, uint32 path_len,
wasi_filestat_t *filestat)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -908,18 +867,15 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(curfds, fd, return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len,
flags, path, path_len, filestat); filestat);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, wasi_lookupflags_t flags, const char *path,
wasi_lookupflags_t flags, uint32 path_len, wasi_timestamp_t st_atim,
const char *path, uint32 path_len, wasi_timestamp_t st_mtim, wasi_fstflags_t fstflags)
wasi_timestamp_t st_atim,
wasi_timestamp_t st_mtim,
wasi_fstflags_t fstflags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -928,15 +884,14 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_set_times(curfds, fd, return wasmtime_ssp_path_filestat_set_times(
flags, path, path_len, curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags);
st_atim, st_mtim, fstflags);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_symlink(wasm_exec_env_t exec_env, wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
const char *old_path, uint32 old_path_len, uint32 old_path_len, wasi_fd_t fd, const char *new_path,
wasi_fd_t fd, const char *new_path, uint32 new_path_len) uint32 new_path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -946,14 +901,13 @@ wasi_path_symlink(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_symlink(curfds, prestats, return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len,
old_path, old_path_len, fd, fd, new_path, new_path_len);
new_path, new_path_len);
} }
static wasi_errno_t static wasi_errno_t
wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
wasi_fd_t fd, const char *path, uint32 path_len) uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -966,8 +920,8 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
wasi_fd_t fd, const char *path, uint32 path_len) const char *path, uint32 path_len)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -980,9 +934,8 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_poll_oneoff(wasm_exec_env_t exec_env, wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
const wasi_subscription_t *in, wasi_event_t *out, wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
uint32 nsubscriptions, uint32 *nevents_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -998,8 +951,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
|| !validate_native_addr(nevents_app, sizeof(uint32))) || !validate_native_addr(nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_poll_oneoff(curfds, in, out, err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
nsubscriptions, &nevents);
if (err) if (err)
return err; return err;
@ -1035,12 +987,9 @@ wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
wasi_fd_t sock, uint32 ri_data_len, wasi_riflags_t ri_flags,
iovec_app_t *ri_data, uint32 ri_data_len, uint32 *ro_datalen_app, wasi_roflags_t *ro_flags)
wasi_riflags_t ri_flags,
uint32 *ro_datalen_app,
wasi_roflags_t *ro_flags)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -1077,10 +1026,8 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
iovec->buf_len = ri_data->buf_len; iovec->buf_len = ri_data->buf_len;
} }
err = wasmtime_ssp_sock_recv(curfds, sock, err = wasmtime_ssp_sock_recv(curfds, sock, iovec_begin, ri_data_len,
iovec_begin, ri_data_len, ri_flags, &ro_datalen, ro_flags);
ri_flags, &ro_datalen,
ro_flags);
if (err) if (err)
goto fail; goto fail;
@ -1095,11 +1042,9 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_send(wasm_exec_env_t exec_env, wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
wasi_fd_t sock,
const iovec_app_t *si_data, uint32 si_data_len, const iovec_app_t *si_data, uint32 si_data_len,
wasi_siflags_t si_flags, wasi_siflags_t si_flags, uint32 *so_datalen_app)
uint32 *so_datalen_app)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -1135,8 +1080,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
ciovec->buf_len = si_data->buf_len; ciovec->buf_len = si_data->buf_len;
} }
err = wasmtime_ssp_sock_send(curfds, sock, err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len,
ciovec_begin, si_data_len,
si_flags, &so_datalen); si_flags, &so_datalen);
if (err) if (err)
goto fail; goto fail;
@ -1152,8 +1096,7 @@ fail:
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
wasi_fd_t sock, wasi_sdflags_t how)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -1171,8 +1114,10 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
return wasmtime_ssp_sched_yield(); return wasmtime_ssp_sched_yield();
} }
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, wasi_##func_name, signature, NULL } { #func_name, wasi_##func_name, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = { static NativeSymbol native_symbols_libc_wasi[] = {
REG_NATIVE_FUNC(args_get, "(**)i"), REG_NATIVE_FUNC(args_get, "(**)i"),
@ -1228,4 +1173,3 @@ get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis)
*p_libc_wasi_apis = native_symbols_libc_wasi; *p_libc_wasi_apis = native_symbols_libc_wasi;
return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol); return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
} }

View File

@ -1,6 +1,8 @@
/* /*
* Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. * Part of the Wasmtime Project, under the Apache License v2.0 with
* See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. * LLVM Exceptions. See
* https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE
* for license information.
* *
* This file declares an interface similar to WASI, but augmented to expose * This file declares an interface similar to WASI, but augmented to expose
* some implementation details such as the curfds arguments that we pass * some implementation details such as the curfds arguments that we pass
@ -13,6 +15,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
/* clang-format off */
#ifdef __cplusplus #ifdef __cplusplus
#ifndef _Static_assert #ifndef _Static_assert
#define _Static_assert static_assert #define _Static_assert static_assert
@ -28,7 +32,6 @@
extern "C" { extern "C" {
#endif #endif
_Static_assert(_Alignof(int8_t) == 1, "non-wasi data layout"); _Static_assert(_Alignof(int8_t) == 1, "non-wasi data layout");
_Static_assert(_Alignof(uint8_t) == 1, "non-wasi data layout"); _Static_assert(_Alignof(uint8_t) == 1, "non-wasi data layout");
_Static_assert(_Alignof(int16_t) == 2, "non-wasi data layout"); _Static_assert(_Alignof(int16_t) == 2, "non-wasi data layout");
@ -891,5 +894,6 @@ __wasi_errno_t wasmtime_ssp_sched_yield(void)
#undef WASMTIME_SSP_SYSCALL_NAME #undef WASMTIME_SSP_SYSCALL_NAME
#endif /* clang-format on */
#endif /* end of WASMTIME_SSP_H */

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -50,8 +52,10 @@ struct LOCKABLE mutex {
pthread_mutex_t object; pthread_mutex_t object;
}; };
/* clang-format off */
#define MUTEX_INITIALIZER \ #define MUTEX_INITIALIZER \
{ PTHREAD_MUTEX_INITIALIZER } { PTHREAD_MUTEX_INITIALIZER }
/* clang-format on */
static inline bool static inline bool
mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock) mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
@ -117,14 +121,15 @@ rwlock_destroy(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
struct LOCKABLE cond { struct LOCKABLE cond {
pthread_cond_t object; pthread_cond_t object;
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \ #if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP || !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
clockid_t clock; clockid_t clock;
#endif #endif
}; };
static inline bool static inline bool
cond_init_monotonic(struct cond *cond) { cond_init_monotonic(struct cond *cond)
{
bool ret = false; bool ret = false;
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK #if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
pthread_condattr_t attr; pthread_condattr_t attr;
@ -147,8 +152,8 @@ fail:
ret = true; ret = true;
#endif #endif
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \ #if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP || !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_MONOTONIC; cond->clock = CLOCK_MONOTONIC;
#endif #endif
return ret; return ret;
@ -159,28 +164,29 @@ cond_init_realtime(struct cond *cond)
{ {
if (pthread_cond_init(&cond->object, NULL) != 0) if (pthread_cond_init(&cond->object, NULL) != 0)
return false; return false;
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \ #if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP || !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_REALTIME; cond->clock = CLOCK_REALTIME;
#endif #endif
return true; return true;
} }
static inline void static inline void
cond_destroy(struct cond *cond) { cond_destroy(struct cond *cond)
{
pthread_cond_destroy(&cond->object); pthread_cond_destroy(&cond->object);
} }
static inline void static inline void
cond_signal(struct cond *cond) { cond_signal(struct cond *cond)
{
pthread_cond_signal(&cond->object); pthread_cond_signal(&cond->object);
} }
#if !CONFIG_HAS_CLOCK_NANOSLEEP #if !CONFIG_HAS_CLOCK_NANOSLEEP
static inline bool static inline bool
cond_timedwait(struct cond *cond, struct mutex *lock, cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
uint64_t timeout, bool abstime) bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
{ {
int ret; int ret;
struct timespec ts = { struct timespec ts = {
@ -220,8 +226,8 @@ cond_timedwait(struct cond *cond, struct mutex *lock,
else { else {
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP #if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
/* Implementation supports relative timeouts. */ /* Implementation supports relative timeouts. */
ret = pthread_cond_timedwait_relative_np(&cond->object, ret = pthread_cond_timedwait_relative_np(&cond->object, &lock->object,
&lock->object, &ts); &ts);
bh_assert((ret == 0 || ret == ETIMEDOUT) bh_assert((ret == 0 || ret == ETIMEDOUT)
&& "pthread_cond_timedwait_relative_np() failed"); && "pthread_cond_timedwait_relative_np() failed");
return ret == ETIMEDOUT; return ret == ETIMEDOUT;

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -44,17 +46,24 @@ struct argv_environ_values {
size_t environ_count; size_t environ_count;
}; };
bool fd_table_init(struct fd_table *); bool
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int); fd_table_init(struct fd_table *);
bool fd_prestats_init(struct fd_prestats *); bool
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t); fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
bool argv_environ_init(struct argv_environ_values *argv_environ, bool
char *argv_buf, size_t argv_buf_size, fd_prestats_init(struct fd_prestats *);
char **argv_list, size_t argc, bool
fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
bool
argv_environ_init(struct argv_environ_values *argv_environ, char *argv_buf,
size_t argv_buf_size, char **argv_list, size_t argc,
char *environ_buf, size_t environ_buf_size, char *environ_buf, size_t environ_buf_size,
char **environ_list, size_t environ_count); char **environ_list, size_t environ_count);
void argv_environ_destroy(struct argv_environ_values *argv_environ); void
void fd_table_destroy(struct fd_table *ft); argv_environ_destroy(struct argv_environ_values *argv_environ);
void fd_prestats_destroy(struct fd_prestats *pt); void
fd_table_destroy(struct fd_table *ft);
void
fd_prestats_destroy(struct fd_prestats *pt);
#endif #endif

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -18,8 +20,11 @@
struct name { \ struct name { \
struct type *l_first; \ struct type *l_first; \
} }
/* clang-format off */
#define LIST_HEAD_INITIALIZER(head) \ #define LIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
/* clang-format on */
#define LIST_ENTRY(type) \ #define LIST_ENTRY(type) \
struct { \ struct { \
@ -29,10 +34,12 @@
#define LIST_FOREACH(var, head, field) \ #define LIST_FOREACH(var, head, field) \
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next) for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
#define LIST_INIT(head) \ #define LIST_INIT(head) \
do { \ do { \
(head)->l_first = NULL; \ (head)->l_first = NULL; \
} while (0) } while (0)
#define LIST_INSERT_HEAD(head, element, field) \ #define LIST_INSERT_HEAD(head, element, field) \
do { \ do { \
(element)->field.l_next = (head)->l_first; \ (element)->field.l_next = (head)->l_first; \
@ -41,6 +48,7 @@
(head)->l_first = (element); \ (head)->l_first = (element); \
(element)->field.l_prev = &(head)->l_first; \ (element)->field.l_prev = &(head)->l_first; \
} while (0) } while (0)
#define LIST_REMOVE(element, field) \ #define LIST_REMOVE(element, field) \
do { \ do { \
if ((element)->field.l_next != NULL) \ if ((element)->field.l_next != NULL) \

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -15,7 +17,9 @@
#if CONFIG_HAS_ARC4RANDOM_BUF #if CONFIG_HAS_ARC4RANDOM_BUF
void random_buf(void *buf, size_t len) { void
random_buf(void *buf, size_t len)
{
arc4random_buf(buf, len); arc4random_buf(buf, len);
} }
@ -25,7 +29,9 @@ void random_buf(void *buf, size_t len) {
#include <sys/random.h> #include <sys/random.h>
#endif #endif
void random_buf(void *buf, size_t len) { void
random_buf(void *buf, size_t len)
{
for (;;) { for (;;) {
ssize_t x = getrandom(buf, len, 0); ssize_t x = getrandom(buf, len, 0);
if (x < 0) { if (x < 0) {
@ -45,7 +51,9 @@ void random_buf(void *buf, size_t len) {
static int urandom; static int urandom;
static void open_urandom(void) { static void
open_urandom(void)
{
urandom = open("/dev/urandom", O_RDONLY); urandom = open("/dev/urandom", O_RDONLY);
if (urandom < 0) { if (urandom < 0) {
os_printf("Failed to open /dev/urandom\n"); os_printf("Failed to open /dev/urandom\n");
@ -53,7 +61,9 @@ static void open_urandom(void) {
} }
} }
void random_buf(void *buf, size_t len) { void
random_buf(void *buf, size_t len)
{
static pthread_once_t open_once = PTHREAD_ONCE_INIT; static pthread_once_t open_once = PTHREAD_ONCE_INIT;
pthread_once(&open_once, open_urandom); pthread_once(&open_once, open_urandom);
@ -72,7 +82,9 @@ void random_buf(void *buf, size_t len) {
// arc4random() until it lies within the range [2^k % upper, 2^k). As // arc4random() until it lies within the range [2^k % upper, 2^k). As
// this range has length k * upper, we can safely obtain a number // this range has length k * upper, we can safely obtain a number
// without any modulo bias. // without any modulo bias.
uintmax_t random_uniform(uintmax_t upper) { uintmax_t
random_uniform(uintmax_t upper)
{
// Compute 2^k % upper // Compute 2^k % upper
// == (2^k - upper) % upper // == (2^k - upper) % upper
// == -upper % upper. // == -upper % upper.

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -12,7 +14,8 @@
#ifndef RANDOM_H #ifndef RANDOM_H
#define RANDOM_H #define RANDOM_H
void random_buf(void *, size_t); void
random_buf(void *, size_t);
uintmax_t random_uniform(uintmax_t); uintmax_t random_uniform(uintmax_t);
#endif #endif

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -46,8 +48,8 @@ refcount_acquire(struct refcount *r) PRODUCES(*r)
static inline bool static inline bool
refcount_release(struct refcount *r) CONSUMES(*r) refcount_release(struct refcount *r) CONSUMES(*r)
{ {
int old = (int)atomic_fetch_sub_explicit(&r->count, 1, int old =
memory_order_release); (int)atomic_fetch_sub_explicit(&r->count, 1, memory_order_release);
bh_assert(old != 0 && "Reference count becoming negative"); bh_assert(old != 0 && "Reference count becoming negative");
return old == 1; return old == 1;
} }

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -12,6 +14,8 @@
#ifndef RIGHTS_H #ifndef RIGHTS_H
#define RIGHTS_H #define RIGHTS_H
/* clang-format off */
#define RIGHTS_ALL \ #define RIGHTS_ALL \
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \ (__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \ __WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
@ -80,4 +84,6 @@
__WASI_RIGHT_POLL_FD_READWRITE) __WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_TTY_INHERITING 0 #define RIGHTS_TTY_INHERITING 0
/* clang-format on */
#endif #endif

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -12,6 +14,7 @@
#ifndef SIGNALS_H #ifndef SIGNALS_H
#define SIGNALS_H #define SIGNALS_H
void signals_init(void); void
signals_init(void);
#endif #endif

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -14,7 +16,8 @@
#include <stdlib.h> #include <stdlib.h>
#if defined(__FreeBSD__) || defined(__APPLE__) || (defined(ANDROID) && __ANDROID_API__ < 28) #if defined(__FreeBSD__) || defined(__APPLE__) \
|| (defined(ANDROID) && __ANDROID_API__ < 28)
#define CONFIG_HAS_ARC4RANDOM_BUF 1 #define CONFIG_HAS_ARC4RANDOM_BUF 1
#else #else
#define CONFIG_HAS_ARC4RANDOM_BUF 0 #define CONFIG_HAS_ARC4RANDOM_BUF 0
@ -22,10 +25,9 @@
// On Linux, prefer to use getrandom, though it isn't available in // On Linux, prefer to use getrandom, though it isn't available in
// GLIBC before 2.25. // GLIBC before 2.25.
#if defined(__linux__) && \ #if defined(__linux__) \
(!defined(__GLIBC__) || \ && (!defined(__GLIBC__) || __GLIBC__ > 2 \
__GLIBC__ > 2 || \ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
(__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#define CONFIG_HAS_GETRANDOM 1 #define CONFIG_HAS_GETRANDOM 1
#else #else
#define CONFIG_HAS_GETRANDOM 0 #define CONFIG_HAS_GETRANDOM 0

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -27,7 +29,8 @@ bh_strndup(const char *s, size_t n)
} }
char * char *
str_nullterminate(const char *s, size_t len) { str_nullterminate(const char *s, size_t len)
{
/* Copy string */ /* Copy string */
char *ret = bh_strndup(s, len); char *ret = bh_strndup(s, len);

View File

@ -1,5 +1,7 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information. // Exceptions. See
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
// information.
// //
// Significant parts of this file are derived from cloudabi-utils. See // Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE // https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE
@ -14,6 +16,7 @@
#include "ssp_config.h" #include "ssp_config.h"
char *str_nullterminate(const char *, size_t); char *
str_nullterminate(const char *, size_t);
#endif #endif

View File

@ -7,7 +7,6 @@
typedef struct { typedef struct {
bh_list_link l; bh_list_link l;
void (*destroy_cb)(WASMCluster *); void (*destroy_cb)(WASMCluster *);
} DestroyCallBackNode; } DestroyCallBackNode;
@ -133,8 +132,7 @@ wasm_cluster_create(WASMExecEnv *exec_env)
} }
/* Prepare the aux stack top and size for every thread */ /* Prepare the aux stack top and size for every thread */
if (!wasm_exec_env_get_aux_stack(exec_env, if (!wasm_exec_env_get_aux_stack(exec_env, &aux_stack_start,
&aux_stack_start,
&aux_stack_size)) { &aux_stack_size)) {
LOG_VERBOSE("No aux stack info for this module, can't create thread"); LOG_VERBOSE("No aux stack info for this module, can't create thread");
@ -215,8 +213,8 @@ destroy_cluster_visitor(void *node, void *user_data)
void void
wasm_cluster_destroy(WASMCluster *cluster) wasm_cluster_destroy(WASMCluster *cluster)
{ {
traverse_list(destroy_callback_list, traverse_list(destroy_callback_list, destroy_cluster_visitor,
destroy_cluster_visitor, (void *)cluster); (void *)cluster);
/* Remove the cluster from the cluster list */ /* Remove the cluster from the cluster list */
os_mutex_lock(&cluster_list_lock); os_mutex_lock(&cluster_list_lock);
@ -338,21 +336,19 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
return NULL; return NULL;
} }
if (!(new_module_inst = if (!(new_module_inst = wasm_runtime_instantiate_internal(
wasm_runtime_instantiate_internal(module, true, 8192, module, true, 8192, 0, NULL, 0))) {
0, NULL, 0))) {
return NULL; return NULL;
} }
if (module_inst) { if (module_inst) {
/* Set custom_data to new module instance */ /* Set custom_data to new module instance */
wasm_runtime_set_custom_data_internal( wasm_runtime_set_custom_data_internal(
new_module_inst, new_module_inst, wasm_runtime_get_custom_data(module_inst));
wasm_runtime_get_custom_data(module_inst));
} }
new_exec_env = wasm_exec_env_create_internal( new_exec_env = wasm_exec_env_create_internal(new_module_inst,
new_module_inst, exec_env->wasm_stack_size); exec_env->wasm_stack_size);
if (!new_exec_env) if (!new_exec_env)
goto fail1; goto fail1;
@ -432,8 +428,7 @@ thread_manager_start_routine(void *arg)
int32 int32
wasm_cluster_create_thread(WASMExecEnv *exec_env, wasm_cluster_create_thread(WASMExecEnv *exec_env,
wasm_module_inst_t module_inst, wasm_module_inst_t module_inst,
void* (*thread_routine)(void *), void *(*thread_routine)(void *), void *arg)
void *arg)
{ {
WASMCluster *cluster; WASMCluster *cluster;
WASMExecEnv *new_exec_env; WASMExecEnv *new_exec_env;
@ -443,8 +438,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
cluster = wasm_exec_env_get_cluster(exec_env); cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster); bh_assert(cluster);
new_exec_env = wasm_exec_env_create_internal( new_exec_env =
module_inst, exec_env->wasm_stack_size); wasm_exec_env_create_internal(module_inst, exec_env->wasm_stack_size);
if (!new_exec_env) if (!new_exec_env)
return -1; return -1;
@ -466,7 +461,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
new_exec_env->thread_start_routine = thread_routine; new_exec_env->thread_start_routine = thread_routine;
new_exec_env->thread_arg = arg; new_exec_env->thread_arg = arg;
if (0 != os_thread_create(&tid, thread_manager_start_routine, if (0
!= os_thread_create(&tid, thread_manager_start_routine,
(void *)new_exec_env, (void *)new_exec_env,
APP_THREAD_STACK_SIZE_DEFAULT)) { APP_THREAD_STACK_SIZE_DEFAULT)) {
goto fail3; goto fail3;
@ -520,7 +516,8 @@ wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status)
} }
inline static bool inline static bool
wasm_cluster_thread_is_running(WASMExecEnv *exec_env) { wasm_cluster_thread_is_running(WASMExecEnv *exec_env)
{
return exec_env->current_status->running_status == STATUS_RUNNING return exec_env->current_status->running_status == STATUS_RUNNING
|| exec_env->current_status->running_status == STATUS_STEP; || exec_env->current_status->running_status == STATUS_STEP;
} }
@ -576,21 +573,23 @@ wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo)
} }
} }
void wasm_cluster_thread_exited(WASMExecEnv *exec_env) void
wasm_cluster_thread_exited(WASMExecEnv *exec_env)
{ {
exec_env->current_status->running_status = STATUS_EXIT; exec_env->current_status->running_status = STATUS_EXIT;
os_cond_signal(&exec_env->current_status->wait_cond); os_cond_signal(&exec_env->current_status->wait_cond);
} }
void wasm_cluster_thread_continue(WASMExecEnv *exec_env) void
wasm_cluster_thread_continue(WASMExecEnv *exec_env)
{ {
wasm_cluster_clear_thread_signal(exec_env); wasm_cluster_clear_thread_signal(exec_env);
exec_env->current_status->running_status = STATUS_RUNNING; exec_env->current_status->running_status = STATUS_RUNNING;
os_cond_signal(&exec_env->wait_cond); os_cond_signal(&exec_env->wait_cond);
} }
void wasm_cluster_thread_step(WASMExecEnv *exec_env) void
wasm_cluster_thread_step(WASMExecEnv *exec_env)
{ {
exec_env->current_status->running_status = STATUS_STEP; exec_env->current_status->running_status = STATUS_STEP;
os_cond_signal(&exec_env->wait_cond); os_cond_signal(&exec_env->wait_cond);
@ -678,16 +677,15 @@ terminate_thread_visitor(void *node, void *user_data)
void void
wasm_cluster_terminate_all(WASMCluster *cluster) wasm_cluster_terminate_all(WASMCluster *cluster)
{ {
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, terminate_thread_visitor, NULL);
terminate_thread_visitor, NULL);
} }
void void
wasm_cluster_terminate_all_except_self(WASMCluster *cluster, wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
WASMExecEnv *exec_env) WASMExecEnv *exec_env)
{ {
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, terminate_thread_visitor,
terminate_thread_visitor, (void *)exec_env); (void *)exec_env);
} }
bool bool
@ -726,16 +724,15 @@ suspend_thread_visitor(void *node, void *user_data)
void void
wasm_cluster_suspend_all(WASMCluster *cluster) wasm_cluster_suspend_all(WASMCluster *cluster)
{ {
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, suspend_thread_visitor, NULL);
suspend_thread_visitor, NULL);
} }
void void
wasm_cluster_suspend_all_except_self(WASMCluster *cluster, wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
WASMExecEnv *exec_env) WASMExecEnv *exec_env)
{ {
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, suspend_thread_visitor,
suspend_thread_visitor, (void *)exec_env); (void *)exec_env);
} }
void void
@ -765,8 +762,7 @@ set_exception_visitor(void *node, void *user_data)
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
WASMExecEnv *exec_env = (WASMExecEnv *)user_data; WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env); WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env);
WASMModuleInstanceCommon *curr_module_inst = WASMModuleInstanceCommon *curr_module_inst = get_module_inst(curr_exec_env);
get_module_inst(curr_exec_env);
const char *exception = wasm_runtime_get_exception(module_inst); const char *exception = wasm_runtime_get_exception(module_inst);
/* skip "Exception: " */ /* skip "Exception: " */
exception += 11; exception += 11;
@ -806,7 +802,6 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
cluster = wasm_exec_env_get_cluster(exec_env); cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster); bh_assert(cluster);
traverse_list(&cluster->exec_env_list, traverse_list(&cluster->exec_env_list, set_custom_data_visitor,
set_custom_data_visitor,
custom_data); custom_data);
} }

View File

@ -26,14 +26,12 @@ extern "C" {
#define STATUS_EXIT (2) #define STATUS_EXIT (2)
#define STATUS_STEP (3) #define STATUS_STEP (3)
#define IS_WAMR_TERM_SIG(signo) \ #define IS_WAMR_TERM_SIG(signo) ((signo) == WAMR_SIG_TERM)
((signo) == WAMR_SIG_TERM)
#define IS_WAMR_STOP_SIG(signo) \ #define IS_WAMR_STOP_SIG(signo) \
((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP) ((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
typedef struct WASMCurrentEnvStatus typedef struct WASMCurrentEnvStatus {
{
uint64 signal_flag : 32; uint64 signal_flag : 32;
uint64 step_count : 16; uint64 step_count : 16;
uint64 running_status : 16; uint64 running_status : 16;
@ -72,8 +70,7 @@ void
wasm_cluster_thread_step(WASMExecEnv *exec_env); wasm_cluster_thread_step(WASMExecEnv *exec_env);
#endif #endif
typedef struct WASMCluster typedef struct WASMCluster {
{
struct WASMCluster *next; struct WASMCluster *next;
korp_mutex lock; korp_mutex lock;
@ -89,7 +86,8 @@ typedef struct WASMCluster
bool *stack_segment_occupied; bool *stack_segment_occupied;
} WASMCluster; } WASMCluster;
void wasm_cluster_set_max_thread_num(uint32 num); void
wasm_cluster_set_max_thread_num(uint32 num);
bool bool
thread_manager_init(); thread_manager_init();
@ -112,8 +110,7 @@ wasm_exec_env_get_cluster(WASMExecEnv *exec_env);
int32 int32
wasm_cluster_create_thread(WASMExecEnv *exec_env, wasm_cluster_create_thread(WASMExecEnv *exec_env,
wasm_module_inst_t module_inst, wasm_module_inst_t module_inst,
void* (*thread_routine)(void *), void *(*thread_routine)(void *), void *arg);
void *arg);
int32 int32
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val); wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val);