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,10 +5,9 @@
#include "aot.h" #include "aot.h"
static char aot_error[128]; static char aot_error[128];
char* char *
aot_get_last_error() aot_get_last_error()
{ {
return aot_error[0] == '\0' ? "" : aot_error; return aot_error[0] == '\0' ? "" : aot_error;
@ -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;
} }
@ -236,7 +238,7 @@ aot_create_func_types(const WASMModule *module)
uint32 i; uint32 i;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTFuncType*) * (uint64)module->type_count; size = sizeof(AOTFuncType *) * (uint64)module->type_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(func_types = wasm_runtime_malloc((uint32)size))) { || !(func_types = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -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;
@ -321,9 +324,8 @@ aot_create_funcs(const WASMModule *module)
uint32 i, j; uint32 i, j;
/* 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;
} }
@ -333,7 +335,7 @@ aot_create_funcs(const WASMModule *module)
/* Create each function */ /* Create each function */
for (i = 0; i < module->function_count; i++) { for (i = 0; i < module->function_count; i++) {
WASMFunction *func = module->functions[i]; WASMFunction *func = module->functions[i];
size = sizeof (AOTFunc); size = sizeof(AOTFunc);
if (!(funcs[i] = wasm_runtime_malloc((uint32)size))) { if (!(funcs[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
goto fail; goto fail;
@ -364,7 +366,7 @@ fail:
return NULL; return NULL;
} }
AOTCompData* AOTCompData *
aot_create_comp_data(WASMModule *module) aot_create_comp_data(WASMModule *module)
{ {
AOTCompData *comp_data; AOTCompData *comp_data;
@ -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

@ -22,7 +22,7 @@ typedef WASMType AOTFuncType;
typedef WASMExport AOTExport; typedef WASMExport AOTExport;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
typedef void * dwar_extractor_handle_t; typedef void *dwar_extractor_handle_t;
#endif #endif
typedef enum AOTIntCond { typedef enum AOTIntCond {
@ -266,13 +266,13 @@ typedef struct AOTNativeSymbol {
int32 index; int32 index;
} AOTNativeSymbol; } AOTNativeSymbol;
AOTCompData* AOTCompData *
aot_create_comp_data(WASMModule *module); aot_create_comp_data(WASMModule *module);
void void
aot_destroy_comp_data(AOTCompData *comp_data); aot_destroy_comp_data(AOTCompData *comp_data);
char* char *
aot_get_last_error(); aot_get_last_error();
void void
@ -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) \
aot_set_last_error_v("call %s failed in %s:%d", (callee),\ do { \
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,27 +344,23 @@ 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
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name); 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
@ -525,7 +526,7 @@ get_exports_size(AOTExport *exports, uint32 export_count)
AOTExport *export = exports; AOTExport *export = exports;
uint32 size = 0, i; uint32 size = 0, i;
for (i = 0; i < export_count; i++, export++) { for (i = 0; i < export_count; i++, export ++) {
size = align_uint(size, 4); size = align_uint(size, 4);
size += get_export_size(export); size += get_export_size(export);
} }
@ -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;
@ -618,7 +614,7 @@ get_relocation_symbol_index(const char *symbol_name,
} }
sym = sym->next; sym = sym->next;
index ++; index++;
} }
/* Not found in symbol_list, add it */ /* Not found in symbol_list, add it */
@ -638,7 +634,7 @@ get_relocation_symbol_index(const char *symbol_name,
symbol_list->end->next = sym; symbol_list->end->next = sym;
symbol_list->end = sym; symbol_list->end = sym;
} }
symbol_list->len ++; symbol_list->len++;
if (is_new) if (is_new)
*is_new = true; *is_new = true;
@ -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);
} }
@ -901,9 +895,9 @@ static void
exchange_uint128(uint8 *pData) exchange_uint128(uint8 *pData)
{ {
/* swap high 64bit and low 64bit */ /* swap high 64bit and low 64bit */
uint64 value = *(uint64*)pData; uint64 value = *(uint64 *)pData;
*(uint64*)pData = *(uint64*)(pData + 8); *(uint64 *)pData = *(uint64 *)(pData + 8);
*(uint64*)(pData + 8) = value; *(uint64 *)(pData + 8) = value;
/* exchange high 64bit */ /* exchange high 64bit */
exchange_uint64(pData); exchange_uint64(pData);
/* exchange low 64bit */ /* exchange low 64bit */
@ -917,48 +911,54 @@ 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()) \
exchange_uint16((uint8*)&t); \ exchange_uint16((uint8 *)&t); \
*(uint16*)(buf + offset) = t; \ *(uint16 *)(buf + offset) = t; \
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()) \
exchange_uint32((uint8*)&t); \ exchange_uint32((uint8 *)&t); \
*(uint32*)(buf + offset) = t; \ *(uint32 *)(buf + offset) = t; \
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()) \
exchange_uint64((uint8*)&t); \ exchange_uint64((uint8 *)&t); \
PUT_U64_TO_ADDR(buf + offset, t); \ PUT_U64_TO_ADDR(buf + offset, t); \
offset += (uint32)sizeof(uint64); \ offset += (uint32)sizeof(uint64); \
} while (0) } while (0)
#define EMIT_V128(v) do { \ #define EMIT_V128(v) \
uint64 *t = (uint64*)v.i64x2; \ do { \
uint64 *t = (uint64 *)v.i64x2; \
CHECK_BUF(16); \ CHECK_BUF(16); \
if (!is_little_endian()) \ if (!is_little_endian()) \
exchange_uint128((uint8 *)t); \ exchange_uint128((uint8 *)t); \
@ -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);
@ -1420,7 +1424,7 @@ aot_emit_export_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U32(section_size); EMIT_U32(section_size);
EMIT_U32(export_count); EMIT_U32(export_count);
for (i = 0; i < export_count; i++, export++) { for (i = 0; i < export_count; i++, export ++) {
offset = align_uint(offset, 4); offset = align_uint(offset, 4);
EMIT_U32(export->index); EMIT_U32(export->index);
EMIT_U8(export->kind); EMIT_U8(export->kind);
@ -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;
@ -1450,7 +1455,7 @@ aot_emit_relocation_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
/* emit symbol offsets */ /* emit symbol offsets */
sym = (AOTSymbolNode *)(obj_data->symbol_list.head); sym = (AOTSymbolNode *)(obj_data->symbol_list.head);
while(sym) { while (sym) {
EMIT_U32(symbol_offset); EMIT_U32(symbol_offset);
/* string_len + str[0 .. string_len - 1] */ /* string_len + str[0 .. string_len - 1] */
symbol_offset += (uint32)sizeof(uint16) + sym->str_len; symbol_offset += (uint32)sizeof(uint16) + sym->str_len;
@ -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,12 +1661,12 @@ 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())) \
exchange_##type((uint8*)&tmp); \ exchange_##type((uint8 *)&tmp); \
obj_data->target_info.f = tmp; \ obj_data->target_info.f = tmp; \
} while (0) } while (0)
@ -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
@ -1687,7 +1691,7 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
obj_data->target_info.bin_type = bin_type - LLVMBinaryTypeELF32L; obj_data->target_info.bin_type = bin_type - LLVMBinaryTypeELF32L;
if (bin_type == LLVMBinaryTypeCOFF) { if (bin_type == LLVMBinaryTypeCOFF) {
struct coff_hdr * coff_header; struct coff_hdr *coff_header;
if (!elf_buf || elf_size < sizeof(struct coff_hdr)) { if (!elf_buf || elf_size < sizeof(struct coff_hdr)) {
aot_set_last_error("invalid coff_hdr buffer."); aot_set_last_error("invalid coff_hdr buffer.");
@ -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,11 +2306,10 @@ 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");
unlink(buf); unlink(buf);
if (ret != 0) { if (ret != 0) {
@ -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))
@ -2355,9 +2360,8 @@ fail:
return NULL; return NULL;
} }
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,31 +15,30 @@
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; \
} \ } \
} while (0) } while (0)
@ -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
@ -135,7 +137,7 @@ find_next_llvm_end_block(AOTBlock *block)
return block ? block->llvm_end_block : NULL; return block ? block->llvm_end_block : NULL;
} }
static AOTBlock* static AOTBlock *
get_target_block(AOTFuncContext *func_ctx, uint32 br_depth) get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
{ {
uint32 i = br_depth; uint32 i = br_depth;
@ -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,22 +160,22 @@ 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; \
} \ } \
\ \
LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \ LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \
} while (0) } while (0)
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,30 +11,33 @@
#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 { \
aot_set_last_error("llvm build "name" fail."); \ if (!(res = \
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
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; \
} \ } \
\ \
LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \ LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \
} while (0) } while (0)
#if LLVM_VERSION_NUMBER >= 12 #if LLVM_VERSION_NUMBER >= 12
#define IS_CONST_ZERO(val) \ #define IS_CONST_ZERO(val) \
@ -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)) { \
@ -95,9 +104,10 @@
return false; \ return false; \
} \ } \
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); \
@ -107,9 +117,10 @@
return false; \ return false; \
} \ } \
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)) { \
@ -118,9 +129,10 @@
return false; \ return false; \
} \ } \
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); \
@ -130,26 +142,27 @@
return false; \ return false; \
} \ } \
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 */
@ -466,7 +454,7 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* fall to default */ /* fall to default */
goto handle_default; goto handle_default;
} }
handle_default: handle_default:
default: default:
/* Build div */ /* Build div */
switch (arith_op) { switch (arith_op) {
@ -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_ */

File diff suppressed because it is too large Load Diff

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
@ -337,7 +336,7 @@ enum {
AOT_LLVMIR_OPT_FILE, AOT_LLVMIR_OPT_FILE,
}; };
typedef struct AOTCompOption{ typedef struct AOTCompOption {
bool is_jit_mode; bool is_jit_mode;
bool is_indirect_mode; bool is_indirect_mode;
char *target_arch; char *target_arch;
@ -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);
@ -372,7 +370,7 @@ aot_get_native_symbol_index(AOTCompContext *comp_ctx, const char *symbol);
bool bool
aot_compile_wasm(AOTCompContext *comp_ctx); aot_compile_wasm(AOTCompContext *comp_ctx);
uint8* uint8 *
aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size); aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size);
void void
@ -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;
@ -43,16 +42,16 @@ typedef struct dwar_extractor
static bool is_debugger_initialized; static bool is_debugger_initialized;
dwar_extractor_handle_t dwar_extractor_handle_t
create_dwarf_extractor(AOTCompData *comp_data, char * file_name) create_dwarf_extractor(AOTCompData *comp_data, char *file_name)
{ {
char *arch = NULL; char *arch = NULL;
char *platform = NULL; char *platform = NULL;
dwar_extractor * extractor = NULL; dwar_extractor *extractor = NULL;
//__attribute__((constructor)) may be better? //__attribute__((constructor)) may be better?
if (!is_debugger_initialized) { if (!is_debugger_initialized) {
SBError error = SBDebugger::InitializeWithErrorHandling(); SBError error = SBDebugger::InitializeWithErrorHandling();
if(error.Fail()) { if (error.Fail()) {
LOG_ERROR("Init Dwarf Debugger failed"); LOG_ERROR("Init Dwarf Debugger failed");
return TO_HANDLE(NULL); return TO_HANDLE(NULL);
} }
@ -62,7 +61,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char * file_name)
SBError error; SBError error;
SBFileSpec exe_file_spec(file_name, true); SBFileSpec exe_file_spec(file_name, true);
if (!(extractor = new dwar_extractor()) ) { if (!(extractor = new dwar_extractor())) {
LOG_ERROR("Create Dwarf Extractor error: failed to allocate memory"); LOG_ERROR("Create Dwarf Extractor error: failed to allocate memory");
goto fail3; goto fail3;
} }
@ -104,7 +103,7 @@ fail3:
void void
destroy_dwarf_extractor(dwar_extractor_handle_t handle) destroy_dwarf_extractor(dwar_extractor_handle_t handle)
{ {
dwar_extractor * extractor = TO_EXTACTOR(handle); dwar_extractor *extractor = TO_EXTACTOR(handle);
if (!extractor) if (!extractor)
return; return;
extractor->debugger.DeleteTarget(extractor->target); extractor->debugger.DeleteTarget(extractor->target);
@ -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, LLVMDIFlagZero);
line_entry.GetLine(), voidpionter, true, LLVMValueRef Param = LLVMGetParam(func_ctx->func, 0);
LLVMDIFlagZero); LLVMBasicBlockRef block_curr = LLVMGetEntryBasicBlock(func_ctx->func);
LLVMValueRef Param = LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar, ParamExpression,
LLVMGetParam(func_ctx->func, 0); ParamLocation, block_curr);
LLVMBasicBlockRef 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());
@ -391,7 +386,7 @@ lldb_function_to_function_dbi(AOTCompContext *comp_ctx, SBSymbolContext &sc, AOT
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable( LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
DIB, FunctionMetadata, variable.GetName(), DIB, FunctionMetadata, variable.GetName(),
strlen(variable.GetName()), function_arg_idx + 1 + 1, strlen(variable.GetName()), function_arg_idx + 1 + 1,
File, //starts form 1, and 1 is exenv, File, // starts form 1, and 1 is exenv,
dec.GetLine(), ParamTypes[function_arg_idx + 1], true, dec.GetLine(), ParamTypes[function_arg_idx + 1], true,
LLVMDIFlagZero); LLVMDIFlagZero);
LLVMValueRef Param = LLVMValueRef Param =
@ -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;
@ -449,7 +441,7 @@ dwarf_get_func_name(AOTCompContext *comp_ctx,
name[0] = '\0'; name[0] = '\0';
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
return ; return;
// A code address in DWARF for WebAssembly is the offset of an // A code address in DWARF for WebAssembly is the offset of an
// instruction relative within the Code section of the WebAssembly file. // instruction relative within the Code section of the WebAssembly file.
@ -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;
@ -484,7 +475,7 @@ dwarf_gen_location(AOTCompContext *comp_ctx,
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction
| eSymbolContextLineEntry)); | eSymbolContextLineEntry));
if (sc.IsValid()) { if (sc.IsValid()) {
//TODO:need to check if the vm_offset is belong to // TODO:need to check if the vm_offset is belong to
SBFunction function(sc.GetFunction()); SBFunction function(sc.GetFunction());
if (function.IsValid()) { if (function.IsValid()) {
uint64_t start = func_ctx->aot_func->code uint64_t start = func_ctx->aot_func->code
@ -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

@ -75,8 +75,9 @@ 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

@ -55,7 +55,7 @@ process_xfer(WASMGDBServer *server, const char *name, char *args)
*args++ = '\0'; *args++ = '\0';
if (!strcmp(name, "libraries") && !strcmp(mode, "read")) { if (!strcmp(name, "libraries") && !strcmp(mode, "read")) {
//TODO: how to get current wasm file name? // TODO: how to get current wasm file name?
uint64_t addr = wasm_debug_instance_get_load_addr( uint64_t addr = wasm_debug_instance_get_load_addr(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
@ -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);
} }
@ -161,10 +162,9 @@ 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;",
@ -183,14 +183,13 @@ handle_generay_query(WASMGDBServer *server, char *payload)
write_packet(server, ""); write_packet(server, "");
} }
if (!strcmp(name, "ProcessInfo")) { if (!strcmp(name, "ProcessInfo")) {
//Todo: process id parent-pid // Todo: process id parent-pid
uint64_t pid; uint64_t pid;
pid = wasm_debug_instance_get_pid( pid = wasm_debug_instance_get_pid(
(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")) {
@ -284,8 +282,9 @@ send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
gdb_status = WAMR_SIG_TRAP; gdb_status = WAMR_SIG_TRAP;
} }
//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;
} }
@ -175,7 +175,7 @@ lib_pthread_destroy()
os_mutex_destroy(&thread_global_lock); os_mutex_destroy(&thread_global_lock);
} }
static ClusterInfoNode* static ClusterInfoNode *
get_cluster_info(WASMCluster *cluster) get_cluster_info(WASMCluster *cluster)
{ {
ClusterInfoNode *node; ClusterInfoNode *node;
@ -195,30 +195,30 @@ get_cluster_info(WASMCluster *cluster)
return NULL; return NULL;
} }
static KeyData* 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);
} }
} }
} }
@ -325,7 +323,7 @@ destroy_thread_key_value_list(bh_list *list)
} }
} }
static ClusterInfoNode* static ClusterInfoNode *
create_cluster_info(WASMCluster *cluster) create_cluster_info(WASMCluster *cluster)
{ {
ClusterInfoNode *node; ClusterInfoNode *node;
@ -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))) {
@ -430,7 +423,7 @@ append_thread_info_node(ThreadInfoNode *thread_info)
return true; return true;
} }
static ThreadInfoNode* static ThreadInfoNode *
get_thread_info(wasm_exec_env_t exec_env, uint32 handle) get_thread_info(wasm_exec_env_t exec_env, uint32 handle)
{ {
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env); WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
@ -453,7 +446,7 @@ allocate_handle()
return id; return id;
} }
static void* static void *
pthread_start_routine(void *arg) pthread_start_routine(void *arg)
{ {
wasm_exec_env_t exec_env = (wasm_exec_env_t)arg; wasm_exec_env_t exec_env = (wasm_exec_env_t)arg;
@ -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;
@ -652,7 +641,7 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
} }
if (retval_offset != 0) if (retval_offset != 0)
*(uint32*)retval = (uint32)(uintptr_t)ret; *(uint32 *)retval = (uint32)(uintptr_t)ret;
return join_ret; return join_ret;
} }
@ -773,7 +762,7 @@ pthread_mutex_init_wrapper(wasm_exec_env_t exec_env, uint32 *mutex, void *attr)
/* Return the mutex handle to app */ /* Return the mutex handle to app */
if (mutex) if (mutex)
*(uint32*)mutex = info_node->handle; *(uint32 *)mutex = info_node->handle;
return 0; return 0;
@ -790,7 +779,7 @@ fail1:
static int32 static int32
pthread_mutex_lock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex) pthread_mutex_lock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
{ {
ThreadInfoNode* info_node = get_thread_info(exec_env, *mutex); ThreadInfoNode *info_node = get_thread_info(exec_env, *mutex);
if (!info_node || info_node->type != T_MUTEX) if (!info_node || info_node->type != T_MUTEX)
return -1; return -1;
@ -800,7 +789,7 @@ pthread_mutex_lock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
static int32 static int32
pthread_mutex_unlock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex) pthread_mutex_unlock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
{ {
ThreadInfoNode* info_node = get_thread_info(exec_env, *mutex); ThreadInfoNode *info_node = get_thread_info(exec_env, *mutex);
if (!info_node || info_node->type != T_MUTEX) if (!info_node || info_node->type != T_MUTEX)
return -1; return -1;
@ -811,7 +800,7 @@ static int32
pthread_mutex_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *mutex) pthread_mutex_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
{ {
int32 ret_val; int32 ret_val;
ThreadInfoNode* info_node = get_thread_info(exec_env, *mutex); ThreadInfoNode *info_node = get_thread_info(exec_env, *mutex);
if (!info_node || info_node->type != T_MUTEX) if (!info_node || info_node->type != T_MUTEX)
return -1; return -1;
@ -852,7 +841,7 @@ pthread_cond_init_wrapper(wasm_exec_env_t exec_env, uint32 *cond, void *attr)
/* Return the cond handle to app */ /* Return the cond handle to app */
if (cond) if (cond)
*(uint32*)cond = info_node->handle; *(uint32 *)cond = info_node->handle;
return 0; return 0;
@ -882,9 +871,10 @@ 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,
uint32 *mutex, uint64 useconds) uint32 *mutex, uint64 useconds)
@ -906,7 +896,7 @@ pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond,
static int32 static int32
pthread_cond_signal_wrapper(wasm_exec_env_t exec_env, uint32 *cond) pthread_cond_signal_wrapper(wasm_exec_env_t exec_env, uint32 *cond)
{ {
ThreadInfoNode* info_node = get_thread_info(exec_env, *cond); ThreadInfoNode *info_node = get_thread_info(exec_env, *cond);
if (!info_node || info_node->type != T_COND) if (!info_node || info_node->type != T_COND)
return -1; return -1;
@ -917,7 +907,7 @@ static int32
pthread_cond_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *cond) pthread_cond_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *cond)
{ {
int32 ret_val; int32 ret_val;
ThreadInfoNode* info_node = get_thread_info(exec_env, *cond); ThreadInfoNode *info_node = get_thread_info(exec_env, *cond);
if (!info_node || info_node->type != T_COND) if (!info_node || info_node->type != T_COND)
return -1; return -1;
@ -1037,24 +1027,28 @@ 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;
*((int32 *)memptr) = module_malloc(size, (void**)&p); *((int32 *)memptr) = module_malloc(size, (void **)&p);
if (!p) if (!p)
return -1; return -1;
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,15 +68,14 @@ 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) \
if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \ do { \
if ((uint8 *)ap + _INTSIZEOF(t) > native_end_addr) \
goto fail; \ goto fail; \
} while (0) } while (0)
/** /**
* @brief Output an unsigned int in hex format * @brief Output an unsigned int in hex format
@ -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;
@ -104,7 +103,7 @@ _printf_hex_uint(out_func_t out, void *ctx,
if (nibble || found_largest_digit || shift == 0) { if (nibble || found_largest_digit || shift == 0) {
found_largest_digit = 1; found_largest_digit = 1;
nibble = (char)(nibble + (nibble > 9 ? 87 : 48)); nibble = (char)(nibble + (nibble > 9 ? 87 : 48));
out((int) nibble, ctx); out((int)nibble, ctx);
digits++; digits++;
continue; continue;
} }
@ -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;
@ -155,17 +153,18 @@ _printf_dec_uint(out_func_t out, void *ctx,
while (pos >= 9) { while (pos >= 9) {
if (found_largest_digit || remainder > pos) { if (found_largest_digit || remainder > pos) {
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) { }
out((int) (padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx); else if (remaining <= min_width && padding < PAD_SPACE_AFTER) {
out((int)(padding == PAD_ZERO_BEFORE ? '0' : ' '), ctx);
digits++; digits++;
} }
remaining--; remaining--;
remainder %= (pos + 1); remainder %= (pos + 1);
pos /= 10; pos /= 10;
} }
out((int) (remainder + 48), ctx); out((int)(remainder + 48), ctx);
if (padding == PAD_SPACE_AFTER) { if (padding == PAD_SPACE_AFTER) {
remaining = min_width - digits; remaining = min_width - 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 */
@ -202,7 +201,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
while (*fmt) { while (*fmt) {
if (!might_format) { if (!might_format) {
if (*fmt != '%') { if (*fmt != '%') {
out((int) *fmt, ctx); out((int)*fmt, ctx);
} }
else { else {
might_format = 1; might_format = 1;
@ -232,10 +231,11 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
case '7': case '7':
case '8': case '8':
case '9': case '9':
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;
@ -337,7 +342,7 @@ handle_1_to_9:
s = start = addr_app_to_native(s_offset); s = start = addr_app_to_native(s_offset);
while (*s) while (*s)
out((int) (*s++), ctx); out((int)(*s++), ctx);
if (padding == PAD_SPACE_AFTER) { if (padding == PAD_SPACE_AFTER) {
int remaining = min_width - (int32)(s - start); int remaining = min_width - (int32)(s - start);
@ -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;
@ -372,20 +380,20 @@ handle_1_to_9:
snprintf(buf, sizeof(buf), "%f", f64); snprintf(buf, sizeof(buf), "%f", f64);
s = buf; s = buf;
while (*s) while (*s)
out((int) (*s++), ctx); out((int)(*s++), ctx);
break; break;
} }
default: default:
out((int) '%', ctx); out((int)'%', ctx);
out((int) *fmt, ctx); out((int)*fmt, ctx);
break; break;
} }
might_format = 0; might_format = 0;
} }
still_might_format: still_might_format:
++fmt; ++fmt;
} }
return true; return true;
@ -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,17 +490,18 @@ 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;
} }
ctx.str = str; ctx.str = str;
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) {
@ -551,7 +562,7 @@ strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
if (str) { if (str) {
len = (uint32)strlen(str) + 1; len = (uint32)strlen(str) + 1;
str_ret_offset = module_malloc(len, (void**)&str_ret); str_ret_offset = module_malloc(len, (void **)&str_ret);
if (str_ret_offset) { if (str_ret_offset) {
bh_memcpy_s(str_ret, len, str, len); bh_memcpy_s(str_ret, len, str, len);
} }
@ -567,21 +578,21 @@ _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);
/* s2 has been checked by runtime */ /* s2 has been checked by runtime */
if (!validate_native_addr((void*)s1, size)) if (!validate_native_addr((void *)s1, size))
return 0; return 0;
return memcmp(s1, s2, size); return memcmp(s1, s2, size);
} }
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,21 +650,20 @@ 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);
/* s2 has been checked by runtime */ /* s2 has been checked by runtime */
if (!validate_native_addr((void*)s1, size)) if (!validate_native_addr((void *)s1, size))
return 0; return 0;
return strncmp(s1, s2, size); return strncmp(s1, s2, size);
@ -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);
@ -716,14 +723,14 @@ static uint32
calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size) calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint64 total_size = (uint64) nmemb * (uint64) size; uint64 total_size = (uint64)nmemb * (uint64)size;
uint32 ret_offset = 0; uint32 ret_offset = 0;
uint8 *ret_ptr; uint8 *ret_ptr;
if (total_size >= UINT32_MAX) if (total_size >= UINT32_MAX)
return 0; return 0;
ret_offset = module_malloc((uint32)total_size, (void**)&ret_ptr); ret_offset = module_malloc((uint32)total_size, (void **)&ret_ptr);
if (ret_offset) { if (ret_offset) {
memset(ret_ptr, 0, (uint32)total_size); memset(ret_ptr, 0, (uint32)total_size);
} }
@ -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;
@ -778,14 +785,14 @@ strtol_wrapper(wasm_exec_env_t exec_env,
return 0; return 0;
num = (int32)strtol(nptr, endptr, base); num = (int32)strtol(nptr, endptr, base);
*(uint32*)endptr = addr_native_to_app(*endptr); *(uint32 *)endptr = addr_native_to_app(*endptr);
return num; return num;
} }
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,13 +808,12 @@ 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;
if (!validate_native_addr((void*)s, n)) if (!validate_native_addr((void *)s, n))
return 0; return 0;
res = memchr(s, c, n); res = memchr(s, c, n);
@ -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 {
@ -955,14 +953,13 @@ bitshift64Lshr_wrapper(wasm_exec_env_t exec_env,
u.value >>= bits; u.value >>= bits;
/* return low 32bit and save high 32bit to temp ret */ /* return low 32bit and save high 32bit to temp ret */
wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32)); wasm_runtime_set_temp_ret(module_inst, (uint32)(u.value >> 32));
return (uint32) u.value; return (uint32)u.value;
} }
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 {
@ -975,8 +972,8 @@ bitshift64Shl_wrapper(wasm_exec_env_t exec_env,
u.value <<= bits; u.value <<= bits;
/* return low 32bit and save high 32bit to temp ret */ /* return low 32bit and save high 32bit to temp ret */
wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32)); wasm_runtime_set_temp_ret(module_inst, (uint32)(u.value >> 32));
return (uint32) u.value; return (uint32)u.value;
} }
static void static void
@ -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,15 +181,14 @@ 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);
int ret; int ret;
struct stat statbuf; struct stat statbuf;
if (!validate_native_addr((void*)statbuf_app, sizeof(struct stat_emcc))) if (!validate_native_addr((void *)statbuf_app, sizeof(struct stat_emcc)))
return -1; return -1;
if (pathname == NULL) if (pathname == NULL)
@ -204,14 +201,14 @@ __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;
struct stat statbuf; struct stat statbuf;
if (!validate_native_addr((void*)statbuf_app, sizeof(struct stat_emcc))) if (!validate_native_addr((void *)statbuf_app, sizeof(struct stat_emcc)))
return -1; return -1;
if (fd <= 0) if (fd <= 0)
@ -224,16 +221,15 @@ __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;
char *buf; char *buf;
int size_read; int size_read;
buf_offset = module_malloc(length, (void**)&buf); buf_offset = module_malloc(length, (void **)&buf);
if (buf_offset == 0) if (buf_offset == 0)
return -1; return -1;
@ -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);
@ -335,12 +332,11 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
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);
@ -373,7 +369,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -387,12 +383,12 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
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);
@ -425,7 +420,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
@ -439,12 +434,11 @@ wasi_fd_read(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
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
@ -586,7 +577,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -600,7 +591,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = iovec_app->buf_len;
} }
@ -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);
@ -953,13 +906,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
if (!uvwasi) if (!uvwasi)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
if (!validate_native_addr((void*)in, sizeof(wasi_subscription_t)) if (!validate_native_addr((void *)in, sizeof(wasi_subscription_t))
|| !validate_native_addr(out, sizeof(wasi_event_t)) || !validate_native_addr(out, sizeof(wasi_event_t))
|| !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);
@ -1033,18 +982,16 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(ri_data->buf_offset); iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset);
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;
*(uint32*)ro_datalen_app = (uint32)ro_datalen; *(uint32 *)ro_datalen_app = (uint32)ro_datalen;
/* success */ /* success */
err = 0; err = 0;
@ -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);
@ -1075,7 +1020,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)si_data_len; total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
if (!validate_native_addr(so_datalen_app, sizeof(uint32)) if (!validate_native_addr(so_datalen_app, sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)si_data, (uint32)total_size)) || !validate_native_addr((void *)si_data, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len; total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
@ -1089,13 +1034,12 @@ wasi_sock_send(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(si_data->buf_offset); ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset);
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;
@ -52,14 +54,13 @@ typedef struct WASIContext {
char **argv_list; char **argv_list;
char *env_buf; char *env_buf;
char **env_list; char **env_list;
} *wasi_ctx_t; } * wasi_ctx_t;
wasi_ctx_t 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;
@ -110,7 +109,7 @@ wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
|| !validate_native_addr(argv_buf, (uint32)argv_buf_size)) || !validate_native_addr(argv_buf, (uint32)argv_buf_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(char*) * ((uint64)argc + 1); total_size = sizeof(char *) * ((uint64)argc + 1);
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
|| !(argv = wasm_runtime_malloc((uint32)total_size))) || !(argv = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
@ -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;
@ -213,7 +211,7 @@ wasi_environ_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(environ_buf, (uint32)environ_buf_size)) || !validate_native_addr(environ_buf, (uint32)environ_buf_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(char*) * (((uint64)environ_count + 1)); total_size = sizeof(char *) * (((uint64)environ_count + 1));
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
|| !(environs = wasm_runtime_malloc((uint32)total_size))) || !(environs = wasm_runtime_malloc((uint32)total_size)))
@ -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);
@ -364,12 +360,12 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
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);
@ -403,7 +399,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -418,12 +414,12 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
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);
@ -457,7 +452,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
@ -472,12 +467,11 @@ wasi_fd_read(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
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
@ -628,7 +619,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32)) if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)iovec_app, (uint32)total_size)) || !validate_native_addr((void *)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -643,12 +634,11 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
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);
@ -993,13 +946,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
if (!validate_native_addr((void*)in, sizeof(wasi_subscription_t)) if (!validate_native_addr((void *)in, sizeof(wasi_subscription_t))
|| !validate_native_addr(out, sizeof(wasi_event_t)) || !validate_native_addr(out, sizeof(wasi_event_t))
|| !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);
@ -1073,18 +1022,16 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void*)addr_app_to_native(ri_data->buf_offset); iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset);
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;
*(uint32*)ro_datalen_app = (uint32)ro_datalen; *(uint32 *)ro_datalen_app = (uint32)ro_datalen;
/* success */ /* success */
err = 0; err = 0;
@ -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);
@ -1116,7 +1061,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
total_size = sizeof(iovec_app_t) * (uint64)si_data_len; total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
if (!validate_native_addr(so_datalen_app, sizeof(uint32)) if (!validate_native_addr(so_datalen_app, sizeof(uint32))
|| total_size >= UINT32_MAX || total_size >= UINT32_MAX
|| !validate_native_addr((void*)si_data, (uint32)total_size)) || !validate_native_addr((void *)si_data, (uint32)total_size))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len; total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
@ -1131,12 +1076,11 @@ wasi_sock_send(wasm_exec_env_t exec_env,
err = (wasi_errno_t)-1; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char*)addr_app_to_native(si_data->buf_offset); ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset);
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;
@ -400,7 +396,7 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
} }
/* start routine of thread manager */ /* start routine of thread manager */
static void* static void *
thread_manager_start_routine(void *arg) thread_manager_start_routine(void *arg)
{ {
void *ret; void *ret;
@ -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;
} }
@ -532,7 +529,7 @@ wasm_cluster_clear_thread_signal(WASMExecEnv *exec_env)
} }
void void
wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 * status) wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 *status)
{ {
os_mutex_lock(&exec_env->current_status->wait_lock); os_mutex_lock(&exec_env->current_status->wait_lock);
while (wasm_cluster_thread_is_running(exec_env)) { while (wasm_cluster_thread_is_running(exec_env)) {
@ -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,20 +26,18 @@ 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;
korp_mutex wait_lock; korp_mutex wait_lock;
korp_cond wait_cond; korp_cond wait_cond;
}WASMCurrentEnvStatus; } WASMCurrentEnvStatus;
WASMCurrentEnvStatus * WASMCurrentEnvStatus *
wasm_cluster_create_exenv_status(); wasm_cluster_create_exenv_status();
@ -57,7 +55,7 @@ void
wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env); wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env);
void void
wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 * status); wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 *status);
void void
wasm_cluster_thread_exited(WASMExecEnv *exec_env); wasm_cluster_thread_exited(WASMExecEnv *exec_env);
@ -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();
@ -106,14 +104,13 @@ void
wasm_cluster_destroy(WASMCluster *cluster); wasm_cluster_destroy(WASMCluster *cluster);
/* Get the cluster of the current exec_env */ /* Get the cluster of the current exec_env */
WASMCluster* WASMCluster *
wasm_exec_env_get_cluster(WASMExecEnv *exec_env); 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);