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)
@ -54,7 +56,7 @@
#define BH_DEBUG 0 #define BH_DEBUG 0
#endif #endif
#define MEM_ALLOCATOR_EMS 0 #define MEM_ALLOCATOR_EMS 0
#define MEM_ALLOCATOR_TLSF 1 #define MEM_ALLOCATOR_TLSF 1
/* Default memory allocator */ /* Default memory allocator */
@ -268,8 +270,8 @@
#define APP_THREAD_STACK_SIZE_DEFAULT (6 * 1024) #define APP_THREAD_STACK_SIZE_DEFAULT (6 * 1024)
#define APP_THREAD_STACK_SIZE_MIN (4 * 1024) #define APP_THREAD_STACK_SIZE_MIN (4 * 1024)
#elif defined(PTHREAD_STACK_DEFAULT) && defined(PTHREAD_STACK_MIN) #elif defined(PTHREAD_STACK_DEFAULT) && defined(PTHREAD_STACK_MIN)
#define APP_THREAD_STACK_SIZE_DEFAULT PTHREAD_STACK_DEFAULT #define APP_THREAD_STACK_SIZE_DEFAULT PTHREAD_STACK_DEFAULT
#define APP_THREAD_STACK_SIZE_MIN PTHREAD_STACK_MIN #define APP_THREAD_STACK_SIZE_MIN PTHREAD_STACK_MIN
#else #else
#define APP_THREAD_STACK_SIZE_DEFAULT (32 * 1024) #define APP_THREAD_STACK_SIZE_DEFAULT (32 * 1024)
#define APP_THREAD_STACK_SIZE_MIN (24 * 1024) #define APP_THREAD_STACK_SIZE_MIN (24 * 1024)
@ -312,4 +314,3 @@
#endif #endif
#endif /* end of _CONFIG_H_ */ #endif /* end of _CONFIG_H_ */

View File

@ -5,13 +5,12 @@
#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;
} }
void void
@ -26,558 +25,561 @@ aot_set_last_error_v(const char *format, ...)
void void
aot_set_last_error(const char *error) aot_set_last_error(const char *error)
{ {
if (error) if (error)
snprintf(aot_error, sizeof(aot_error), "Error: %s", error); snprintf(aot_error, sizeof(aot_error), "Error: %s", error);
else else
aot_error[0] = '\0'; aot_error[0] = '\0';
} }
static void static void
aot_destroy_mem_init_data_list(AOTMemInitData **data_list, uint32 count) aot_destroy_mem_init_data_list(AOTMemInitData **data_list, uint32 count)
{ {
uint32 i; uint32 i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (data_list[i]) if (data_list[i])
wasm_runtime_free(data_list[i]); wasm_runtime_free(data_list[i]);
wasm_runtime_free(data_list); wasm_runtime_free(data_list);
} }
static AOTMemInitData ** static AOTMemInitData **
aot_create_mem_init_data_list(const WASMModule *module) aot_create_mem_init_data_list(const WASMModule *module)
{ {
AOTMemInitData **data_list; AOTMemInitData **data_list;
uint64 size; uint64 size;
uint32 i; uint32 i;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTMemInitData *) * (uint64)module->data_seg_count; size = sizeof(AOTMemInitData *) * (uint64)module->data_seg_count;
if (size >= UINT32_MAX
|| !(data_list = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
return NULL;
}
memset(data_list, 0, size);
/* Create each memory data segment */
for (i = 0; i < module->data_seg_count; i++) {
size = offsetof(AOTMemInitData, bytes) +
(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 = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
goto fail; return NULL;
} }
#if WASM_ENABLE_BULK_MEMORY != 0 memset(data_list, 0, size);
data_list[i]->is_passive = module->data_segments[i]->is_passive;
data_list[i]->memory_index = module->data_segments[i]->memory_index;
#endif
data_list[i]->offset = module->data_segments[i]->base_offset;
data_list[i]->byte_count = module->data_segments[i]->data_length;
memcpy(data_list[i]->bytes, module->data_segments[i]->data,
module->data_segments[i]->data_length);
}
return data_list; /* Create each memory data segment */
for (i = 0; i < module->data_seg_count; i++) {
size = offsetof(AOTMemInitData, bytes)
+ (uint64)module->data_segments[i]->data_length;
if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
goto fail;
}
#if WASM_ENABLE_BULK_MEMORY != 0
data_list[i]->is_passive = module->data_segments[i]->is_passive;
data_list[i]->memory_index = module->data_segments[i]->memory_index;
#endif
data_list[i]->offset = module->data_segments[i]->base_offset;
data_list[i]->byte_count = module->data_segments[i]->data_length;
memcpy(data_list[i]->bytes, module->data_segments[i]->data,
module->data_segments[i]->data_length);
}
return data_list;
fail: fail:
aot_destroy_mem_init_data_list(data_list, module->data_seg_count); aot_destroy_mem_init_data_list(data_list, module->data_seg_count);
return NULL; return NULL;
} }
static void static void
aot_destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count) aot_destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
{ {
uint32 i; uint32 i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (data_list[i]) if (data_list[i])
wasm_runtime_free(data_list[i]); wasm_runtime_free(data_list[i]);
wasm_runtime_free(data_list); wasm_runtime_free(data_list);
} }
static AOTTableInitData ** static AOTTableInitData **
aot_create_table_init_data_list(const WASMModule *module) aot_create_table_init_data_list(const WASMModule *module)
{ {
AOTTableInitData **data_list; AOTTableInitData **data_list;
uint64 size; uint64 size;
uint32 i; uint32 i;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTTableInitData *) * (uint64)module->table_seg_count; size = sizeof(AOTTableInitData *) * (uint64)module->table_seg_count;
if (size >= UINT32_MAX
|| !(data_list = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
return NULL;
}
memset(data_list, 0, size);
/* Create each table data segment */
for (i = 0; i < module->table_seg_count; i++) {
size = 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 = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
goto fail; return NULL;
} }
data_list[i]->offset = module->table_segments[i].base_offset; memset(data_list, 0, size);
data_list[i]->func_index_count = module->table_segments[i].function_count;
data_list[i]->mode = module->table_segments[i].mode;
data_list[i]->elem_type = module->table_segments[i].elem_type;
/* runtime control it */
data_list[i]->is_dropped = false;
data_list[i]->table_index = module->table_segments[i].table_index;
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
&module->table_segments[i].base_offset, sizeof(AOTInitExpr));
data_list[i]->func_index_count = module->table_segments[i].function_count;
bh_memcpy_s(data_list[i]->func_indexes,
sizeof(uint32) * module->table_segments[i].function_count,
module->table_segments[i].func_indexes,
sizeof(uint32) * module->table_segments[i].function_count);
}
return data_list; /* Create each table data segment */
for (i = 0; i < module->table_seg_count; i++) {
size =
offsetof(AOTTableInitData, func_indexes)
+ sizeof(uint32) * (uint64)module->table_segments[i].function_count;
if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
goto fail;
}
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]->mode = module->table_segments[i].mode;
data_list[i]->elem_type = module->table_segments[i].elem_type;
/* runtime control it */
data_list[i]->is_dropped = false;
data_list[i]->table_index = module->table_segments[i].table_index;
bh_memcpy_s(&data_list[i]->offset, sizeof(AOTInitExpr),
&module->table_segments[i].base_offset,
sizeof(AOTInitExpr));
data_list[i]->func_index_count =
module->table_segments[i].function_count;
bh_memcpy_s(data_list[i]->func_indexes,
sizeof(uint32) * module->table_segments[i].function_count,
module->table_segments[i].func_indexes,
sizeof(uint32) * module->table_segments[i].function_count);
}
return data_list;
fail: fail:
aot_destroy_table_init_data_list(data_list, module->table_seg_count); aot_destroy_table_init_data_list(data_list, module->table_seg_count);
return NULL; return NULL;
} }
static AOTImportGlobal * static AOTImportGlobal *
aot_create_import_globals(const WASMModule *module, aot_create_import_globals(const WASMModule *module,
uint32 *p_import_global_data_size) uint32 *p_import_global_data_size)
{ {
AOTImportGlobal *import_globals; AOTImportGlobal *import_globals;
uint64 size; uint64 size;
uint32 i, data_offset = 0; uint32 i, data_offset = 0;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count; size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(import_globals = wasm_runtime_malloc((uint32)size))) { || !(import_globals = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
memset(import_globals, 0, (uint32)size); memset(import_globals, 0, (uint32)size);
/* Create each import global */ /* Create each import global */
for (i = 0; i < module->import_global_count; i++) { for (i = 0; i < module->import_global_count; i++) {
WASMGlobalImport *import_global = &module->import_globals[i].u.global; WASMGlobalImport *import_global = &module->import_globals[i].u.global;
import_globals[i].module_name = import_global->module_name; import_globals[i].module_name = import_global->module_name;
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_globals[i].size = wasm_value_type_size(import_global->type); import_global->global_data_linked;
/* Calculate data offset */ import_globals[i].size = wasm_value_type_size(import_global->type);
import_globals[i].data_offset = data_offset; /* Calculate data offset */
data_offset += wasm_value_type_size(import_global->type); import_globals[i].data_offset = data_offset;
} data_offset += wasm_value_type_size(import_global->type);
}
*p_import_global_data_size = data_offset; *p_import_global_data_size = data_offset;
return import_globals; return import_globals;
} }
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;
uint64 size; uint64 size;
uint32 i, data_offset = global_data_start_offset; uint32 i, data_offset = global_data_start_offset;
/* 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; }
}
memset(globals, 0, (uint32)size); memset(globals, 0, (uint32)size);
/* Create each global */ /* Create each global */
for (i = 0; i < module->global_count; i++) { for (i = 0; i < module->global_count; i++) {
WASMGlobal *global = &module->globals[i]; WASMGlobal *global = &module->globals[i];
globals[i].type = global->type; globals[i].type = global->type;
globals[i].is_mutable = global->is_mutable; globals[i].is_mutable = global->is_mutable;
globals[i].size = wasm_value_type_size(global->type); globals[i].size = wasm_value_type_size(global->type);
memcpy(&globals[i].init_expr, &global->init_expr, memcpy(&globals[i].init_expr, &global->init_expr,
sizeof(global->init_expr)); sizeof(global->init_expr));
/* Calculate data offset */ /* Calculate data offset */
globals[i].data_offset = data_offset; globals[i].data_offset = data_offset;
data_offset += wasm_value_type_size(global->type); data_offset += wasm_value_type_size(global->type);
} }
*p_global_data_size = data_offset - global_data_start_offset; *p_global_data_size = data_offset - global_data_start_offset;
return globals; return globals;
} }
static void static void
aot_destroy_func_types(AOTFuncType **func_types, uint32 count) aot_destroy_func_types(AOTFuncType **func_types, uint32 count)
{ {
uint32 i; uint32 i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (func_types[i]) if (func_types[i])
wasm_runtime_free(func_types[i]); wasm_runtime_free(func_types[i]);
wasm_runtime_free(func_types); wasm_runtime_free(func_types);
} }
static AOTFuncType ** static AOTFuncType **
aot_create_func_types(const WASMModule *module) aot_create_func_types(const WASMModule *module)
{ {
AOTFuncType **func_types; AOTFuncType **func_types;
uint64 size; uint64 size;
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
|| !(func_types = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
return NULL;
}
memset(func_types, 0, size);
/* Create each function type */
for (i = 0; i < module->type_count; i++) {
size = offsetof(AOTFuncType, types) +
(uint64)module->types[i]->param_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 = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
goto fail; return NULL;
} }
memcpy(func_types[i], module->types[i], size);
}
return func_types; memset(func_types, 0, size);
/* Create each function type */
for (i = 0; i < module->type_count; i++) {
size = offsetof(AOTFuncType, types)
+ (uint64)module->types[i]->param_count
+ (uint64)module->types[i]->result_count;
if (size >= UINT32_MAX
|| !(func_types[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
goto fail;
}
memcpy(func_types[i], module->types[i], size);
}
return func_types;
fail: fail:
aot_destroy_func_types(func_types, module->type_count); aot_destroy_func_types(func_types, module->type_count);
return NULL; return NULL;
} }
static AOTImportFunc * static AOTImportFunc *
aot_create_import_funcs(const WASMModule *module) aot_create_import_funcs(const WASMModule *module)
{ {
AOTImportFunc *import_funcs; AOTImportFunc *import_funcs;
uint64 size; uint64 size;
uint32 i, j; uint32 i, j;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTImportFunc) * (uint64)module->import_function_count; size = sizeof(AOTImportFunc) * (uint64)module->import_function_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(import_funcs = wasm_runtime_malloc((uint32)size))) { || !(import_funcs = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
/* 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 =
import_funcs[i].module_name = import_func->module_name; &module->import_functions[i].u.function;
import_funcs[i].func_name = import_func->field_name; import_funcs[i].module_name = import_func->module_name;
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked; import_funcs[i].func_name = import_func->field_name;
import_funcs[i].func_type = import_func->func_type; import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
import_funcs[i].signature = import_func->signature; import_funcs[i].func_type = import_func->func_type;
import_funcs[i].attachment = import_func->attachment; import_funcs[i].signature = import_func->signature;
import_funcs[i].call_conv_raw = import_func->call_conv_raw; import_funcs[i].attachment = import_func->attachment;
import_funcs[i].call_conv_wasm_c_api = false; import_funcs[i].call_conv_raw = import_func->call_conv_raw;
/* Resolve function type index */ import_funcs[i].call_conv_wasm_c_api = false;
for (j = 0; j < module->type_count; j++) /* Resolve function type index */
if (import_func->func_type == module->types[j]) { for (j = 0; j < module->type_count; j++)
import_funcs[i].func_type_index = j; if (import_func->func_type == module->types[j]) {
break; import_funcs[i].func_type_index = j;
} break;
} }
}
return import_funcs; return import_funcs;
} }
static void static void
aot_destroy_funcs(AOTFunc **funcs, uint32 count) aot_destroy_funcs(AOTFunc **funcs, uint32 count)
{ {
uint32 i; uint32 i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (funcs[i]) if (funcs[i])
wasm_runtime_free(funcs[i]); wasm_runtime_free(funcs[i]);
wasm_runtime_free(funcs); wasm_runtime_free(funcs);
} }
static AOTFunc ** static AOTFunc **
aot_create_funcs(const WASMModule *module) aot_create_funcs(const WASMModule *module)
{ {
AOTFunc **funcs; AOTFunc **funcs;
uint64 size; uint64 size;
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;
}
memset(funcs, 0, size);
/* Create each function */
for (i = 0; i < module->function_count; i++) {
WASMFunction *func = module->functions[i];
size = sizeof (AOTFunc);
if (!(funcs[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
goto fail;
} }
funcs[i]->func_type = func->func_type; memset(funcs, 0, size);
/* Resolve function type index */ /* Create each function */
for (j = 0; j < module->type_count; j++) for (i = 0; i < module->function_count; i++) {
if (func->func_type == module->types[j]) { WASMFunction *func = module->functions[i];
funcs[i]->func_type_index = j; size = sizeof(AOTFunc);
break; if (!(funcs[i] = wasm_runtime_malloc((uint32)size))) {
} aot_set_last_error("allocate memory failed.");
goto fail;
}
/* Resolve local variable info and code info */ funcs[i]->func_type = func->func_type;
funcs[i]->local_count = func->local_count;
funcs[i]->local_types = func->local_types;
funcs[i]->param_cell_num = func->param_cell_num;
funcs[i]->local_cell_num = func->local_cell_num;
funcs[i]->code = func->code;
funcs[i]->code_size = func->code_size;
}
return funcs; /* Resolve function type index */
for (j = 0; j < module->type_count; j++)
if (func->func_type == module->types[j]) {
funcs[i]->func_type_index = j;
break;
}
/* Resolve local variable info and code info */
funcs[i]->local_count = func->local_count;
funcs[i]->local_types = func->local_types;
funcs[i]->param_cell_num = func->param_cell_num;
funcs[i]->local_cell_num = func->local_cell_num;
funcs[i]->code = func->code;
funcs[i]->code_size = func->code_size;
}
return funcs;
fail: fail:
aot_destroy_funcs(funcs, module->function_count); aot_destroy_funcs(funcs, module->function_count);
return NULL; return NULL;
} }
AOTCompData* AOTCompData *
aot_create_comp_data(WASMModule *module) aot_create_comp_data(WASMModule *module)
{ {
AOTCompData *comp_data; AOTCompData *comp_data;
uint32 import_global_data_size = 0, global_data_size = 0, i, j; uint32 import_global_data_size = 0, global_data_size = 0, i, j;
uint64 size; uint64 size;
/* Allocate memory */ /* Allocate memory */
if (!(comp_data = wasm_runtime_malloc(sizeof(AOTCompData)))) { if (!(comp_data = wasm_runtime_malloc(sizeof(AOTCompData)))) {
aot_set_last_error("create compile data failed.\n"); aot_set_last_error("create compile data failed.\n");
return NULL; return NULL;
}
memset(comp_data, 0, sizeof(AOTCompData));
comp_data->memory_count = module->import_memory_count + module->memory_count;
/* TODO: create import memories */
/* Allocate memory for memory array, reserve one AOTMemory space at least */
if (!comp_data->memory_count)
comp_data->memory_count = 1;
size = (uint64)comp_data->memory_count * sizeof(AOTMemory);
if (size >= UINT32_MAX
|| !(comp_data->memories = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("create memories array failed.\n");
goto fail;
}
memset(comp_data->memories, 0, size);
if (!(module->import_memory_count + module->memory_count)) {
comp_data->memories[0].num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
}
/* Set memory page count */
for (i = 0; i < module->import_memory_count + module->memory_count; i++) {
if (i < module->import_memory_count) {
comp_data->memories[i].memory_flags =
module->import_memories[i].u.memory.flags;
comp_data->memories[i].num_bytes_per_page =
module->import_memories[i].u.memory.num_bytes_per_page;
comp_data->memories[i].mem_init_page_count =
module->import_memories[i].u.memory.init_page_count;
comp_data->memories[i].mem_max_page_count =
module->import_memories[i].u.memory.max_page_count;
comp_data->memories[i].num_bytes_per_page =
module->import_memories[i].u.memory.num_bytes_per_page;
} }
else {
j = i - module->import_memory_count;
comp_data->memories[i].memory_flags =
module->memories[j].flags;
comp_data->memories[i].num_bytes_per_page =
module->memories[j].num_bytes_per_page;
comp_data->memories[i].mem_init_page_count =
module->memories[j].init_page_count;
comp_data->memories[i].mem_max_page_count =
module->memories[j].max_page_count;
comp_data->memories[i].num_bytes_per_page =
module->memories[j].num_bytes_per_page;
}
}
/* Create memory data segments */ memset(comp_data, 0, sizeof(AOTCompData));
comp_data->mem_init_data_count = module->data_seg_count;
if (comp_data->mem_init_data_count > 0
&& !(comp_data->mem_init_data_list =
aot_create_mem_init_data_list(module)))
goto fail;
/* Create tables */ comp_data->memory_count =
comp_data->table_count = module->import_table_count + module->table_count; module->import_memory_count + module->memory_count;
if (comp_data->table_count > 0) { /* TODO: create import memories */
size = sizeof(AOTTable) * (uint64)comp_data->table_count;
/* Allocate memory for memory array, reserve one AOTMemory space at least */
if (!comp_data->memory_count)
comp_data->memory_count = 1;
size = (uint64)comp_data->memory_count * sizeof(AOTMemory);
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(comp_data->tables = wasm_runtime_malloc((uint32)size))) { || !(comp_data->memories = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("create memories array failed.\n"); aot_set_last_error("create memories array failed.\n");
goto fail; goto fail;
} }
memset(comp_data->tables, 0, size); memset(comp_data->memories, 0, size);
for (i = 0; i < comp_data->table_count; i++) {
if (i < module->import_table_count) { if (!(module->import_memory_count + module->memory_count)) {
comp_data->tables[i].elem_type = comp_data->memories[0].num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
module->import_tables[i].u.table.elem_type;
comp_data->tables[i].table_flags =
module->import_tables[i].u.table.flags;
comp_data->tables[i].table_init_size =
module->import_tables[i].u.table.init_size;
comp_data->tables[i].table_max_size =
module->import_tables[i].u.table.max_size;
comp_data->tables[i].possible_grow =
module->import_tables[i].u.table.possible_grow;
}
else {
j = i - module->import_table_count;
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_init_size = module->tables[j].init_size;
comp_data->tables[i].table_max_size = module->tables[j].max_size;
comp_data->tables[i].possible_grow = module->tables[j].possible_grow;
}
} }
}
/* Create table data segments */ /* Set memory page count */
comp_data->table_init_data_count = module->table_seg_count; for (i = 0; i < module->import_memory_count + module->memory_count; i++) {
if (comp_data->table_init_data_count > 0 if (i < module->import_memory_count) {
&& !(comp_data->table_init_data_list = comp_data->memories[i].memory_flags =
aot_create_table_init_data_list(module))) module->import_memories[i].u.memory.flags;
goto fail; comp_data->memories[i].num_bytes_per_page =
module->import_memories[i].u.memory.num_bytes_per_page;
comp_data->memories[i].mem_init_page_count =
module->import_memories[i].u.memory.init_page_count;
comp_data->memories[i].mem_max_page_count =
module->import_memories[i].u.memory.max_page_count;
comp_data->memories[i].num_bytes_per_page =
module->import_memories[i].u.memory.num_bytes_per_page;
}
else {
j = i - module->import_memory_count;
comp_data->memories[i].memory_flags = module->memories[j].flags;
comp_data->memories[i].num_bytes_per_page =
module->memories[j].num_bytes_per_page;
comp_data->memories[i].mem_init_page_count =
module->memories[j].init_page_count;
comp_data->memories[i].mem_max_page_count =
module->memories[j].max_page_count;
comp_data->memories[i].num_bytes_per_page =
module->memories[j].num_bytes_per_page;
}
}
/* Create import globals */ /* Create memory data segments */
comp_data->import_global_count = module->import_global_count; comp_data->mem_init_data_count = module->data_seg_count;
if (comp_data->import_global_count > 0 if (comp_data->mem_init_data_count > 0
&& !(comp_data->import_globals = && !(comp_data->mem_init_data_list =
aot_create_import_globals(module, &import_global_data_size))) aot_create_mem_init_data_list(module)))
goto fail; goto fail;
/* Create globals */ /* Create tables */
comp_data->global_count = module->global_count; comp_data->table_count = module->import_table_count + module->table_count;
if (comp_data->global_count
&& !(comp_data->globals = aot_create_globals
(module, import_global_data_size, &global_data_size)))
goto fail;
comp_data->global_data_size = import_global_data_size + if (comp_data->table_count > 0) {
global_data_size; size = sizeof(AOTTable) * (uint64)comp_data->table_count;
if (size >= UINT32_MAX
|| !(comp_data->tables = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("create memories array failed.\n");
goto fail;
}
memset(comp_data->tables, 0, size);
for (i = 0; i < comp_data->table_count; i++) {
if (i < module->import_table_count) {
comp_data->tables[i].elem_type =
module->import_tables[i].u.table.elem_type;
comp_data->tables[i].table_flags =
module->import_tables[i].u.table.flags;
comp_data->tables[i].table_init_size =
module->import_tables[i].u.table.init_size;
comp_data->tables[i].table_max_size =
module->import_tables[i].u.table.max_size;
comp_data->tables[i].possible_grow =
module->import_tables[i].u.table.possible_grow;
}
else {
j = i - module->import_table_count;
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_init_size =
module->tables[j].init_size;
comp_data->tables[i].table_max_size =
module->tables[j].max_size;
comp_data->tables[i].possible_grow =
module->tables[j].possible_grow;
}
}
}
/* Create function types */ /* Create table data segments */
comp_data->func_type_count = module->type_count; comp_data->table_init_data_count = module->table_seg_count;
if (comp_data->func_type_count if (comp_data->table_init_data_count > 0
&& !(comp_data->func_types = aot_create_func_types(module))) && !(comp_data->table_init_data_list =
goto fail; aot_create_table_init_data_list(module)))
goto fail;
/* Create import functions */ /* Create import globals */
comp_data->import_func_count = module->import_function_count; comp_data->import_global_count = module->import_global_count;
if (comp_data->import_func_count if (comp_data->import_global_count > 0
&& !(comp_data->import_funcs = aot_create_import_funcs(module))) && !(comp_data->import_globals =
goto fail; aot_create_import_globals(module, &import_global_data_size)))
goto fail;
/* Create functions */ /* Create globals */
comp_data->func_count = module->function_count; comp_data->global_count = module->global_count;
if (comp_data->func_count if (comp_data->global_count
&& !(comp_data->funcs = aot_create_funcs(module))) && !(comp_data->globals = aot_create_globals(
goto fail; module, import_global_data_size, &global_data_size)))
goto fail;
/* Create aux data/heap/stack information */ comp_data->global_data_size = import_global_data_size + global_data_size;
comp_data->aux_data_end_global_index = module->aux_data_end_global_index;
comp_data->aux_data_end = module->aux_data_end;
comp_data->aux_heap_base_global_index = module->aux_heap_base_global_index;
comp_data->aux_heap_base = module->aux_heap_base;
comp_data->aux_stack_top_global_index = module->aux_stack_top_global_index;
comp_data->aux_stack_bottom = module->aux_stack_bottom;
comp_data->aux_stack_size = module->aux_stack_size;
comp_data->start_func_index = module->start_function; /* Create function types */
comp_data->malloc_func_index = module->malloc_function; comp_data->func_type_count = module->type_count;
comp_data->free_func_index = module->free_function; if (comp_data->func_type_count
comp_data->retain_func_index = module->retain_function; && !(comp_data->func_types = aot_create_func_types(module)))
goto fail;
comp_data->wasm_module = module; /* Create import functions */
comp_data->import_func_count = module->import_function_count;
if (comp_data->import_func_count
&& !(comp_data->import_funcs = aot_create_import_funcs(module)))
goto fail;
return comp_data; /* Create functions */
comp_data->func_count = module->function_count;
if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
goto fail;
/* Create aux data/heap/stack information */
comp_data->aux_data_end_global_index = module->aux_data_end_global_index;
comp_data->aux_data_end = module->aux_data_end;
comp_data->aux_heap_base_global_index = module->aux_heap_base_global_index;
comp_data->aux_heap_base = module->aux_heap_base;
comp_data->aux_stack_top_global_index = module->aux_stack_top_global_index;
comp_data->aux_stack_bottom = module->aux_stack_bottom;
comp_data->aux_stack_size = module->aux_stack_size;
comp_data->start_func_index = module->start_function;
comp_data->malloc_func_index = module->malloc_function;
comp_data->free_func_index = module->free_function;
comp_data->retain_func_index = module->retain_function;
comp_data->wasm_module = module;
return comp_data;
fail: fail:
aot_destroy_comp_data(comp_data); aot_destroy_comp_data(comp_data);
return NULL; return NULL;
} }
void void
aot_destroy_comp_data(AOTCompData *comp_data) aot_destroy_comp_data(AOTCompData *comp_data)
{ {
if (!comp_data) if (!comp_data)
return; return;
if (comp_data->import_memories) if (comp_data->import_memories)
wasm_runtime_free(comp_data->import_memories); wasm_runtime_free(comp_data->import_memories);
if (comp_data->memories) if (comp_data->memories)
wasm_runtime_free(comp_data->memories); wasm_runtime_free(comp_data->memories);
if (comp_data->mem_init_data_list) if (comp_data->mem_init_data_list)
aot_destroy_mem_init_data_list(comp_data->mem_init_data_list, aot_destroy_mem_init_data_list(comp_data->mem_init_data_list,
comp_data->mem_init_data_count); comp_data->mem_init_data_count);
if (comp_data->import_tables) if (comp_data->import_tables)
wasm_runtime_free(comp_data->import_tables); wasm_runtime_free(comp_data->import_tables);
if (comp_data->tables) if (comp_data->tables)
wasm_runtime_free(comp_data->tables); wasm_runtime_free(comp_data->tables);
if (comp_data->table_init_data_list) if (comp_data->table_init_data_list)
aot_destroy_table_init_data_list(comp_data->table_init_data_list, aot_destroy_table_init_data_list(comp_data->table_init_data_list,
comp_data->table_init_data_count); comp_data->table_init_data_count);
if (comp_data->import_globals) if (comp_data->import_globals)
wasm_runtime_free(comp_data->import_globals); wasm_runtime_free(comp_data->import_globals);
if (comp_data->globals) if (comp_data->globals)
wasm_runtime_free(comp_data->globals); wasm_runtime_free(comp_data->globals);
if (comp_data->func_types) if (comp_data->func_types)
aot_destroy_func_types(comp_data->func_types, aot_destroy_func_types(comp_data->func_types,
comp_data->func_type_count); comp_data->func_type_count);
if (comp_data->import_funcs) if (comp_data->import_funcs)
wasm_runtime_free(comp_data->import_funcs); wasm_runtime_free(comp_data->import_funcs);
if (comp_data->funcs) if (comp_data->funcs)
aot_destroy_funcs(comp_data->funcs, comp_data->func_count); aot_destroy_funcs(comp_data->funcs, comp_data->func_count);
wasm_runtime_free(comp_data); wasm_runtime_free(comp_data);
} }

View File

@ -22,54 +22,54 @@ 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 {
INT_EQZ = 0, INT_EQZ = 0,
INT_EQ, INT_EQ,
INT_NE, INT_NE,
INT_LT_S, INT_LT_S,
INT_LT_U, INT_LT_U,
INT_GT_S, INT_GT_S,
INT_GT_U, INT_GT_U,
INT_LE_S, INT_LE_S,
INT_LE_U, INT_LE_U,
INT_GE_S, INT_GE_S,
INT_GE_U INT_GE_U
} AOTIntCond; } AOTIntCond;
typedef enum AOTFloatCond { typedef enum AOTFloatCond {
FLOAT_EQ = 0, FLOAT_EQ = 0,
FLOAT_NE, FLOAT_NE,
FLOAT_LT, FLOAT_LT,
FLOAT_GT, FLOAT_GT,
FLOAT_LE, FLOAT_LE,
FLOAT_GE, FLOAT_GE,
FLOAT_UNO FLOAT_UNO
} AOTFloatCond; } AOTFloatCond;
/** /**
* Import memory * Import memory
*/ */
typedef struct AOTImportMemory { typedef struct AOTImportMemory {
char *module_name; char *module_name;
char *memory_name; char *memory_name;
uint32 memory_flags; uint32 memory_flags;
uint32 num_bytes_per_page; uint32 num_bytes_per_page;
uint32 mem_init_page_count; uint32 mem_init_page_count;
uint32 mem_max_page_count; uint32 mem_max_page_count;
} AOTImportMemory; } AOTImportMemory;
/** /**
* Memory information * Memory information
*/ */
typedef struct AOTMemory { typedef struct AOTMemory {
/* memory info */ /* memory info */
uint32 memory_flags; uint32 memory_flags;
uint32 num_bytes_per_page; uint32 num_bytes_per_page;
uint32 mem_init_page_count; uint32 mem_init_page_count;
uint32 mem_max_page_count; uint32 mem_max_page_count;
} AOTMemory; } AOTMemory;
/** /**
@ -77,202 +77,202 @@ typedef struct AOTMemory {
*/ */
typedef struct AOTMemInitData { typedef struct AOTMemInitData {
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
/* Passive flag */ /* Passive flag */
bool is_passive; bool is_passive;
/* memory index */ /* memory index */
uint32 memory_index; uint32 memory_index;
#endif #endif
/* Start address of init data */ /* Start address of init data */
AOTInitExpr offset; AOTInitExpr offset;
/* Byte count */ /* Byte count */
uint32 byte_count; uint32 byte_count;
/* Byte array */ /* Byte array */
uint8 bytes[1]; uint8 bytes[1];
} AOTMemInitData; } AOTMemInitData;
/** /**
* Import table * Import table
*/ */
typedef struct AOTImportTable { typedef struct AOTImportTable {
char *module_name; char *module_name;
char *table_name; char *table_name;
uint32 table_flags; uint32 table_flags;
uint32 table_init_size; uint32 table_init_size;
uint32 table_max_size; uint32 table_max_size;
bool possible_grow; bool possible_grow;
} AOTImportTable; } AOTImportTable;
/** /**
* Table * Table
*/ */
typedef struct AOTTable { typedef struct AOTTable {
uint32 elem_type; uint32 elem_type;
uint32 table_flags; uint32 table_flags;
uint32 table_init_size; uint32 table_init_size;
uint32 table_max_size; uint32 table_max_size;
bool possible_grow; bool possible_grow;
} AOTTable; } AOTTable;
/** /**
* A segment of table init data * A segment of table init data
*/ */
typedef struct AOTTableInitData { typedef struct AOTTableInitData {
/* 0 to 7 */ /* 0 to 7 */
uint32 mode; uint32 mode;
/* funcref or externref, elemkind will be considered as funcref */ /* funcref or externref, elemkind will be considered as funcref */
uint32 elem_type; uint32 elem_type;
bool is_dropped; bool is_dropped;
/* optional, only for active */ /* optional, only for active */
uint32 table_index; uint32 table_index;
/* Start address of init data */ /* Start address of init data */
AOTInitExpr offset; AOTInitExpr offset;
/* Function index count */ /* Function index count */
uint32 func_index_count; uint32 func_index_count;
/* Function index array */ /* Function index array */
uint32 func_indexes[1]; uint32 func_indexes[1];
} AOTTableInitData; } AOTTableInitData;
/** /**
* Import global variable * Import global variable
*/ */
typedef struct AOTImportGlobal { typedef struct AOTImportGlobal {
char *module_name; char *module_name;
char *global_name; char *global_name;
/* VALUE_TYPE_I32/I64/F32/F64 */ /* VALUE_TYPE_I32/I64/F32/F64 */
uint8 type; uint8 type;
bool is_mutable; bool is_mutable;
uint32 size; uint32 size;
/* The data offset of current global in global data */ /* The data offset of current global in global data */
uint32 data_offset; uint32 data_offset;
/* global data after linked */ /* global data after linked */
WASMValue global_data_linked; WASMValue global_data_linked;
} AOTImportGlobal; } AOTImportGlobal;
/** /**
* Global variable * Global variable
*/ */
typedef struct AOTGlobal { typedef struct AOTGlobal {
/* VALUE_TYPE_I32/I64/F32/F64 */ /* VALUE_TYPE_I32/I64/F32/F64 */
uint8 type; uint8 type;
bool is_mutable; bool is_mutable;
uint32 size; uint32 size;
/* The data offset of current global in global data */ /* The data offset of current global in global data */
uint32 data_offset; uint32 data_offset;
AOTInitExpr init_expr; AOTInitExpr init_expr;
} AOTGlobal; } AOTGlobal;
/** /**
* Import function * Import function
*/ */
typedef struct AOTImportFunc { typedef struct AOTImportFunc {
char *module_name; char *module_name;
char *func_name; char *func_name;
AOTFuncType *func_type; AOTFuncType *func_type;
uint32 func_type_index; uint32 func_type_index;
/* function pointer after linked */ /* function pointer after linked */
void *func_ptr_linked; void *func_ptr_linked;
/* signature from registered native symbols */ /* signature from registered native symbols */
const char *signature; const char *signature;
/* attachment */ /* attachment */
void *attachment; void *attachment;
bool call_conv_raw; bool call_conv_raw;
bool call_conv_wasm_c_api; bool call_conv_wasm_c_api;
bool wasm_c_api_with_env; bool wasm_c_api_with_env;
} AOTImportFunc; } AOTImportFunc;
/** /**
* Function * Function
*/ */
typedef struct AOTFunc { typedef struct AOTFunc {
AOTFuncType *func_type; AOTFuncType *func_type;
uint32 func_type_index; uint32 func_type_index;
uint32 local_count; uint32 local_count;
uint8 *local_types; uint8 *local_types;
uint16 param_cell_num; uint16 param_cell_num;
uint16 local_cell_num; uint16 local_cell_num;
uint32 code_size; uint32 code_size;
uint8 *code; uint8 *code;
} AOTFunc; } AOTFunc;
typedef struct AOTCompData { typedef struct AOTCompData {
/* Import memories */ /* Import memories */
uint32 import_memory_count; uint32 import_memory_count;
AOTImportMemory *import_memories; AOTImportMemory *import_memories;
/* Memories */ /* Memories */
uint32 memory_count; uint32 memory_count;
AOTMemory *memories; AOTMemory *memories;
/* Memory init data info */ /* Memory init data info */
uint32 mem_init_data_count; uint32 mem_init_data_count;
AOTMemInitData **mem_init_data_list; AOTMemInitData **mem_init_data_list;
/* Import tables */ /* Import tables */
uint32 import_table_count; uint32 import_table_count;
AOTImportTable *import_tables; AOTImportTable *import_tables;
/* Tables */ /* Tables */
uint32 table_count; uint32 table_count;
AOTTable *tables; AOTTable *tables;
/* Table init data info */ /* Table init data info */
uint32 table_init_data_count; uint32 table_init_data_count;
AOTTableInitData **table_init_data_list; AOTTableInitData **table_init_data_list;
/* Import globals */ /* Import globals */
uint32 import_global_count; uint32 import_global_count;
AOTImportGlobal *import_globals; AOTImportGlobal *import_globals;
/* Globals */ /* Globals */
uint32 global_count; uint32 global_count;
AOTGlobal *globals; AOTGlobal *globals;
/* Function types */ /* Function types */
uint32 func_type_count; uint32 func_type_count;
AOTFuncType **func_types; AOTFuncType **func_types;
/* Import functions */ /* Import functions */
uint32 import_func_count; uint32 import_func_count;
AOTImportFunc *import_funcs; AOTImportFunc *import_funcs;
/* Functions */ /* Functions */
uint32 func_count; uint32 func_count;
AOTFunc **funcs; AOTFunc **funcs;
uint32 global_data_size; uint32 global_data_size;
uint32 start_func_index; uint32 start_func_index;
uint32 malloc_func_index; uint32 malloc_func_index;
uint32 free_func_index; uint32 free_func_index;
uint32 retain_func_index; uint32 retain_func_index;
uint32 aux_data_end_global_index; uint32 aux_data_end_global_index;
uint32 aux_data_end; uint32 aux_data_end;
uint32 aux_heap_base_global_index; uint32 aux_heap_base_global_index;
uint32 aux_heap_base; uint32 aux_heap_base;
uint32 aux_stack_top_global_index; uint32 aux_stack_top_global_index;
uint32 aux_stack_bottom; uint32 aux_stack_bottom;
uint32 aux_stack_size; uint32 aux_stack_size;
WASMModule *wasm_module; WASMModule *wasm_module;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
dwar_extractor_handle_t extractor; dwar_extractor_handle_t extractor;
#endif #endif
} AOTCompData; } AOTCompData;
typedef struct AOTNativeSymbol { typedef struct AOTNativeSymbol {
bh_list_link link; bh_list_link link;
const char *symbol; const char *symbol;
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,14 +282,16 @@ 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 { \
__FUNCTION__, __LINE__); \ aot_set_last_error_v("call %s failed in %s:%d", (callee), \
} while (0) __FUNCTION__, __LINE__); \
} while (0)
#else #else
#define HANDLE_FAILURE(callee) do { \ #define HANDLE_FAILURE(callee) \
aot_set_last_error_v("call %s failed", (callee)); \ do { \
} while (0) aot_set_last_error_v("call %s failed", (callee)); \
} while (0)
#endif #endif
static inline uint32 static inline uint32
@ -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

@ -17,142 +17,144 @@ typedef AOTIntCond IntCond;
typedef AOTFloatCond FloatCond; typedef AOTFloatCond FloatCond;
typedef enum IntArithmetic { typedef enum IntArithmetic {
INT_ADD = 0, INT_ADD = 0,
INT_SUB, INT_SUB,
INT_MUL, INT_MUL,
INT_DIV_S, INT_DIV_S,
INT_DIV_U, INT_DIV_U,
INT_REM_S, INT_REM_S,
INT_REM_U INT_REM_U
} IntArithmetic; } IntArithmetic;
typedef enum V128Arithmetic { typedef enum V128Arithmetic {
V128_ADD = 0, V128_ADD = 0,
V128_SUB, V128_SUB,
V128_MUL, V128_MUL,
V128_DIV, V128_DIV,
V128_NEG, V128_NEG,
V128_MIN, V128_MIN,
V128_MAX, V128_MAX,
} V128Arithmetic; } V128Arithmetic;
typedef enum IntBitwise { typedef enum IntBitwise {
INT_AND = 0, INT_AND = 0,
INT_OR, INT_OR,
INT_XOR, INT_XOR,
} IntBitwise; } IntBitwise;
typedef enum V128Bitwise { typedef enum V128Bitwise {
V128_NOT, V128_NOT,
V128_AND, V128_AND,
V128_ANDNOT, V128_ANDNOT,
V128_OR, V128_OR,
V128_XOR, V128_XOR,
V128_BITSELECT, V128_BITSELECT,
} V128Bitwise; } V128Bitwise;
typedef enum IntShift { typedef enum IntShift {
INT_SHL = 0, INT_SHL = 0,
INT_SHR_S, INT_SHR_S,
INT_SHR_U, INT_SHR_U,
INT_ROTL, INT_ROTL,
INT_ROTR INT_ROTR
} IntShift; } IntShift;
typedef enum FloatMath { typedef enum FloatMath {
FLOAT_ABS = 0, FLOAT_ABS = 0,
FLOAT_NEG, FLOAT_NEG,
FLOAT_CEIL, FLOAT_CEIL,
FLOAT_FLOOR, FLOAT_FLOOR,
FLOAT_TRUNC, FLOAT_TRUNC,
FLOAT_NEAREST, FLOAT_NEAREST,
FLOAT_SQRT FLOAT_SQRT
} FloatMath; } FloatMath;
typedef enum FloatArithmetic { typedef enum FloatArithmetic {
FLOAT_ADD = 0, FLOAT_ADD = 0,
FLOAT_SUB, FLOAT_SUB,
FLOAT_MUL, FLOAT_MUL,
FLOAT_DIV, FLOAT_DIV,
FLOAT_MIN, FLOAT_MIN,
FLOAT_MAX, FLOAT_MAX,
} FloatArithmetic; } FloatArithmetic;
static inline bool static inline bool
check_type_compatible(uint8 src_type, uint8 dst_type) check_type_compatible(uint8 src_type, uint8 dst_type)
{ {
if (src_type == dst_type) { if (src_type == dst_type) {
return true; return true;
} }
/* ext i1 to i32 */ /* ext i1 to i32 */
if (src_type == VALUE_TYPE_I1 && dst_type == VALUE_TYPE_I32) { if (src_type == VALUE_TYPE_I1 && dst_type == VALUE_TYPE_I32) {
return true; return true;
} }
/* i32 <==> func.ref, i32 <==> extern.ref */ /* i32 <==> func.ref, i32 <==> extern.ref */
if (src_type == VALUE_TYPE_I32 if (src_type == VALUE_TYPE_I32
&& (dst_type == VALUE_TYPE_EXTERNREF && (dst_type == VALUE_TYPE_EXTERNREF
|| dst_type == VALUE_TYPE_FUNCREF)) { || dst_type == VALUE_TYPE_FUNCREF)) {
return true; return true;
} }
if (dst_type == VALUE_TYPE_I32 if (dst_type == VALUE_TYPE_I32
&& (src_type == VALUE_TYPE_FUNCREF && (src_type == VALUE_TYPE_FUNCREF
|| src_type == VALUE_TYPE_EXTERNREF)) { || src_type == VALUE_TYPE_EXTERNREF)) {
return true; return true;
} }
return false; return false;
} }
#define CHECK_STACK() do { \ #define CHECK_STACK() \
if (!func_ctx->block_stack.block_list_end) { \ do { \
aot_set_last_error("WASM block stack underflow."); \ if (!func_ctx->block_stack.block_list_end) { \
goto fail; \ aot_set_last_error("WASM block stack underflow."); \
} \ goto fail; \
if (!func_ctx->block_stack.block_list_end-> \ } \
value_stack.value_list_end) { \ if (!func_ctx->block_stack.block_list_end->value_stack \
aot_set_last_error("WASM data stack underflow."); \ .value_list_end) { \
goto fail; \ aot_set_last_error("WASM data stack underflow."); \
} \ goto fail; \
} while (0) } \
} while (0)
#define POP(llvm_value, value_type) do { \ #define POP(llvm_value, value_type) \
AOTValue *aot_value; \ do { \
CHECK_STACK(); \ AOTValue *aot_value; \
aot_value = aot_value_stack_pop \ CHECK_STACK(); \
(&func_ctx->block_stack.block_list_end->value_stack); \ aot_value = aot_value_stack_pop( \
if (!check_type_compatible(aot_value->type, \ &func_ctx->block_stack.block_list_end->value_stack); \
value_type)) { \ if (!check_type_compatible(aot_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; \
} \ } \
if (aot_value->type == value_type) \ if (aot_value->type == value_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, \
aot_set_last_error("invalid WASM stack " \ I32_TYPE, "i1toi32"))) { \
"data type."); \ aot_set_last_error("invalid WASM stack " \
wasm_runtime_free(aot_value); \ "data type."); \
goto fail; \ wasm_runtime_free(aot_value); \
} \ goto fail; \
} \ } \
else { \ } \
bh_assert(aot_value->type == VALUE_TYPE_I32 \ else { \
|| aot_value->type == VALUE_TYPE_FUNCREF \ bh_assert(aot_value->type == VALUE_TYPE_I32 \
|| aot_value->type == VALUE_TYPE_EXTERNREF); \ || aot_value->type == VALUE_TYPE_FUNCREF \
bh_assert(value_type == VALUE_TYPE_I32 \ || aot_value->type == VALUE_TYPE_EXTERNREF); \
|| value_type == VALUE_TYPE_FUNCREF \ bh_assert(value_type == VALUE_TYPE_I32 \
|| value_type == VALUE_TYPE_EXTERNREF); \ || value_type == VALUE_TYPE_FUNCREF \
llvm_value = aot_value->value; \ || value_type == VALUE_TYPE_EXTERNREF); \
} \ llvm_value = aot_value->value; \
} \ } \
wasm_runtime_free(aot_value); \ } \
} while (0) wasm_runtime_free(aot_value); \
} while (0)
#define POP_I32(v) POP(v, VALUE_TYPE_I32) #define POP_I32(v) POP(v, VALUE_TYPE_I32)
#define POP_I64(v) POP(v, VALUE_TYPE_I64) #define POP_I64(v) POP(v, VALUE_TYPE_I64)
@ -162,49 +164,50 @@ 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) \
AOTValue *aot_value; \ do { \
CHECK_STACK(); \ AOTValue *aot_value; \
aot_value = aot_value_stack_pop \ CHECK_STACK(); \
(&func_ctx->block_stack.block_list_end->value_stack); \ aot_value = aot_value_stack_pop( \
if (aot_value->type != VALUE_TYPE_I1 \ &func_ctx->block_stack.block_list_end->value_stack); \
&& aot_value->type != VALUE_TYPE_I32) { \ if (aot_value->type != VALUE_TYPE_I1 \
aot_set_last_error("invalid WASM stack data type."); \ && aot_value->type != VALUE_TYPE_I32) { \
wasm_runtime_free(aot_value); \ aot_set_last_error("invalid WASM stack data type."); \
goto fail; \ wasm_runtime_free(aot_value); \
} \ goto fail; \
if (aot_value->type == VALUE_TYPE_I1) \ } \
llvm_value = aot_value->value; \ if (aot_value->type == VALUE_TYPE_I1) \
else { \ llvm_value = aot_value->value; \
if (!(llvm_value = LLVMBuildICmp(comp_ctx->builder, \ else { \
LLVMIntNE, aot_value->value, I32_ZERO, \ if (!(llvm_value = \
"i1_cond"))){ \ LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, \
aot_set_last_error("llvm build trunc failed."); \ aot_value->value, I32_ZERO, "i1_cond"))) { \
wasm_runtime_free(aot_value); \ aot_set_last_error("llvm build trunc failed."); \
goto fail; \ wasm_runtime_free(aot_value); \
} \ goto fail; \
} \ } \
wasm_runtime_free(aot_value); \ } \
} while (0) wasm_runtime_free(aot_value); \
} while (0)
#define PUSH(llvm_value, value_type) do { \ #define PUSH(llvm_value, value_type) \
AOTValue *aot_value; \ do { \
if (!func_ctx->block_stack.block_list_end) { \ AOTValue *aot_value; \
aot_set_last_error("WASM block stack underflow."); \ if (!func_ctx->block_stack.block_list_end) { \
goto fail; \ aot_set_last_error("WASM block stack underflow."); \
} \ goto fail; \
aot_value = wasm_runtime_malloc(sizeof(AOTValue)); \ } \
if (!aot_value) { \ aot_value = wasm_runtime_malloc(sizeof(AOTValue)); \
aot_set_last_error("allocate memory failed."); \ if (!aot_value) { \
goto fail; \ aot_set_last_error("allocate memory failed."); \
} \ goto fail; \
memset(aot_value, 0, sizeof(AOTValue)); \ } \
aot_value->type = value_type; \ memset(aot_value, 0, sizeof(AOTValue)); \
aot_value->value = llvm_value; \ aot_value->type = value_type; \
aot_value_stack_push \ aot_value->value = llvm_value; \
(&func_ctx->block_stack.block_list_end->value_stack,\ aot_value_stack_push( \
aot_value); \ &func_ctx->block_stack.block_list_end->value_stack, aot_value); \
} while (0) } while (0)
#define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32) #define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32)
#define PUSH_I64(v) PUSH(v, VALUE_TYPE_I64) #define PUSH_I64(v) PUSH(v, VALUE_TYPE_I64)
@ -243,31 +246,31 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
#define I8_CONST(v) LLVMConstInt(INT8_TYPE, v, true) #define I8_CONST(v) LLVMConstInt(INT8_TYPE, v, true)
#define LLVM_CONST(name) (comp_ctx->llvm_consts.name) #define LLVM_CONST(name) (comp_ctx->llvm_consts.name)
#define I8_ZERO LLVM_CONST(i8_zero) #define I8_ZERO LLVM_CONST(i8_zero)
#define I32_ZERO LLVM_CONST(i32_zero) #define I32_ZERO LLVM_CONST(i32_zero)
#define I64_ZERO LLVM_CONST(i64_zero) #define I64_ZERO LLVM_CONST(i64_zero)
#define F32_ZERO LLVM_CONST(f32_zero) #define F32_ZERO LLVM_CONST(f32_zero)
#define F64_ZERO LLVM_CONST(f64_zero) #define F64_ZERO LLVM_CONST(f64_zero)
#define I32_ONE LLVM_CONST(i32_one) #define I32_ONE LLVM_CONST(i32_one)
#define I32_TWO LLVM_CONST(i32_two) #define I32_TWO LLVM_CONST(i32_two)
#define I32_THREE LLVM_CONST(i32_three) #define I32_THREE LLVM_CONST(i32_three)
#define I32_FOUR LLVM_CONST(i32_four) #define I32_FOUR LLVM_CONST(i32_four)
#define I32_FIVE LLVM_CONST(i32_five) #define I32_FIVE LLVM_CONST(i32_five)
#define I32_SIX LLVM_CONST(i32_six) #define I32_SIX LLVM_CONST(i32_six)
#define I32_SEVEN LLVM_CONST(i32_seven) #define I32_SEVEN LLVM_CONST(i32_seven)
#define I32_EIGHT LLVM_CONST(i32_eight) #define I32_EIGHT LLVM_CONST(i32_eight)
#define I32_NEG_ONE LLVM_CONST(i32_neg_one) #define I32_NEG_ONE LLVM_CONST(i32_neg_one)
#define I64_NEG_ONE LLVM_CONST(i64_neg_one) #define I64_NEG_ONE LLVM_CONST(i64_neg_one)
#define I32_MIN LLVM_CONST(i32_min) #define I32_MIN LLVM_CONST(i32_min)
#define I64_MIN LLVM_CONST(i64_min) #define I64_MIN LLVM_CONST(i64_min)
#define I32_31 LLVM_CONST(i32_31) #define I32_31 LLVM_CONST(i32_31)
#define I32_32 LLVM_CONST(i32_32) #define I32_32 LLVM_CONST(i32_32)
#define I64_63 LLVM_CONST(i64_63) #define I64_63 LLVM_CONST(i64_63)
#define I64_64 LLVM_CONST(i64_64) #define I64_64 LLVM_CONST(i64_64)
#define REF_NULL I32_NEG_ONE #define REF_NULL I32_NEG_ONE
#define V128_TYPE comp_ctx->basic_types.v128_type #define V128_TYPE comp_ctx->basic_types.v128_type
#define V128_PTR_TYPE comp_ctx->basic_types.v128_ptr_type #define V128_PTR_TYPE comp_ctx->basic_types.v128_ptr_type
#define V128_i8x16_TYPE comp_ctx->basic_types.i8x16_vec_type #define V128_i8x16_TYPE comp_ctx->basic_types.i8x16_vec_type
#define V128_i16x8_TYPE comp_ctx->basic_types.i16x8_vec_type #define V128_i16x8_TYPE comp_ctx->basic_types.i16x8_vec_type
#define V128_i32x4_TYPE comp_ctx->basic_types.i32x4_vec_type #define V128_i32x4_TYPE comp_ctx->basic_types.i32x4_vec_type
@ -282,55 +285,57 @@ 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) \
if (!v) { \ do { \
aot_set_last_error("create llvm const failed."); \ if (!v) { \
goto fail; \ aot_set_last_error("create llvm const failed."); \
} \ 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 = \
aot_set_last_error("llvm add function type failed."); \ LLVMFunctionType(ret_type, param_types, argc, false))) { \
return false; \ aot_set_last_error("llvm add function type failed."); \
} \ return false; \
if (comp_ctx->is_jit_mode) { \ } \
/* JIT mode, call the function directly */ \ if (comp_ctx->is_jit_mode) { \
if (!(func_ptr_type = LLVMPointerType(func_type, 0))) { \ /* JIT mode, call the function directly */ \
aot_set_last_error("llvm add pointer type failed."); \ if (!(func_ptr_type = LLVMPointerType(func_type, 0))) { \
return false; \ aot_set_last_error("llvm add pointer type failed."); \
} \ return false; \
if (!(value = I64_CONST((uint64)(uintptr_t)name)) \ } \
|| !(func = LLVMConstIntToPtr(value, func_ptr_type))) { \ if (!(value = I64_CONST((uint64)(uintptr_t)name)) \
aot_set_last_error("create LLVM value failed."); \ || !(func = LLVMConstIntToPtr(value, func_ptr_type))) { \
return false; \ aot_set_last_error("create LLVM value failed."); \
} \ return false; \
} \ } \
else { \ } \
char *func_name = #name; \ else { \
/* AOT mode, delcare the function */ \ char *func_name = #name; \
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \ /* AOT mode, delcare the function */ \
&& !(func = LLVMAddFunction(comp_ctx->module, \ if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \
func_name, func_type))) { \ && !(func = LLVMAddFunction(comp_ctx->module, func_name, \
aot_set_last_error("llvm add function failed."); \ func_type))) { \
return false; \ aot_set_last_error("llvm add function failed."); \
} \ return false; \
} \ } \
} while (0) } \
} while (0)
bool bool
aot_compile_wasm(AOTCompContext *comp_ctx); aot_compile_wasm(AOTCompContext *comp_ctx);
@ -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,19 +6,24 @@
#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 { \
u.val = (value); \ union { \
((uint32*)(addr))[0] = u.parts[0]; \ uint64 val; \
((uint32*)(addr))[1] = u.parts[1]; \ uint32 parts[2]; \
} while (0) } u; \
u.val = (value); \
((uint32 *)(addr))[0] = u.parts[0]; \
((uint32 *)(addr))[1] = u.parts[1]; \
} while (0)
#define CHECK_SIZE(size) do { \ #define CHECK_SIZE(size) \
if (size == (uint32)-1) { \ do { \
aot_set_last_error("get symbol size failed."); \ if (size == (uint32)-1) { \
return (uint32)-1; \ aot_set_last_error("get symbol size failed."); \
} \ return (uint32)-1; \
} while (0) } \
} while (0)
/* Internal function in object file */ /* Internal function in object file */
typedef struct AOTObjectFunc { typedef struct AOTObjectFunc {
@ -124,9 +129,8 @@ 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:
is_passive (4 bytes) + memory_index (4 bytes) is_passive (4 bytes) + memory_index (4 bytes)
@ -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);
} }
@ -549,15 +550,14 @@ get_relocation_size(AOTRelocation *relocation, bool is_32bin)
if (is_32bin) if (is_32bin)
size = sizeof(uint32) * 2; /* offset and addend */ size = sizeof(uint32) * 2; /* offset and addend */
else else
size = sizeof(uint64) * 2; /* offset and addend */ size = sizeof(uint64) * 2; /* offset and addend */
size += (uint32)sizeof(uint32); /* relocation type */ size += (uint32)sizeof(uint32); /* relocation type */
size += (uint32)sizeof(uint32); /* symbol name index */ size += (uint32)sizeof(uint32); /* symbol name index */
return size; return size;
} }
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;
} }
@ -756,18 +751,17 @@ get_relocation_section_symbol_size(AOTObjectData *obj_data)
get symbol size from symbol list directly in the second calculation */ get symbol size from symbol list directly in the second calculation */
if (obj_data->symbol_list.len > 0) { if (obj_data->symbol_list.len > 0) {
symbol_table_size = symbol_table_size =
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,68 +911,76 @@ 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) \
if (buf + offset + length > buf_end) { \ do { \
aot_set_last_error("buf overflow"); \ if (buf + offset + length > buf_end) { \
return false; \ aot_set_last_error("buf overflow"); \
} \ return false; \
} while (0) } \
} while (0)
#define EMIT_U8(v) do { \ #define EMIT_U8(v) \
CHECK_BUF(1); \ do { \
*(uint8*)(buf + offset) = (uint8)v; \ CHECK_BUF(1); \
offset++; \ *(uint8 *)(buf + offset) = (uint8)v; \
} while (0) offset++; \
} while (0)
#define EMIT_U16(v) do { \ #define EMIT_U16(v) \
uint16 t = (uint16)v; \ do { \
CHECK_BUF(2); \ uint16 t = (uint16)v; \
if (!is_little_endian()) \ CHECK_BUF(2); \
exchange_uint16((uint8*)&t); \ if (!is_little_endian()) \
*(uint16*)(buf + offset) = t; \ exchange_uint16((uint8 *)&t); \
offset += (uint32)sizeof(uint16); \ *(uint16 *)(buf + offset) = t; \
} while (0) offset += (uint32)sizeof(uint16); \
} while (0)
#define EMIT_U32(v) do { \ #define EMIT_U32(v) \
uint32 t = (uint32)v; \ do { \
CHECK_BUF(4); \ uint32 t = (uint32)v; \
if (!is_little_endian()) \ CHECK_BUF(4); \
exchange_uint32((uint8*)&t); \ if (!is_little_endian()) \
*(uint32*)(buf + offset) = t; \ exchange_uint32((uint8 *)&t); \
offset += (uint32)sizeof(uint32); \ *(uint32 *)(buf + offset) = t; \
} while (0) offset += (uint32)sizeof(uint32); \
} while (0)
#define EMIT_U64(v) do { \ #define EMIT_U64(v) \
uint64 t = (uint64)v; \ do { \
CHECK_BUF(8); \ uint64 t = (uint64)v; \
if (!is_little_endian()) \ CHECK_BUF(8); \
exchange_uint64((uint8*)&t); \ if (!is_little_endian()) \
PUT_U64_TO_ADDR(buf + offset, t); \ exchange_uint64((uint8 *)&t); \
offset += (uint32)sizeof(uint64); \ PUT_U64_TO_ADDR(buf + offset, t); \
} while (0) offset += (uint32)sizeof(uint64); \
} while (0)
#define EMIT_V128(v) do { \ #define EMIT_V128(v) \
uint64 *t = (uint64*)v.i64x2; \ do { \
CHECK_BUF(16); \ uint64 *t = (uint64 *)v.i64x2; \
if (!is_little_endian()) \ CHECK_BUF(16); \
exchange_uint128((uint8 *)t); \ if (!is_little_endian()) \
PUT_U64_TO_ADDR(buf + offset, t[0]); \ exchange_uint128((uint8 *)t); \
offset += (uint32)sizeof(uint64); \ PUT_U64_TO_ADDR(buf + offset, t[0]); \
PUT_U64_TO_ADDR(buf + offset, t[1]); \ offset += (uint32)sizeof(uint64); \
offset += (uint32)sizeof(uint64); \ PUT_U64_TO_ADDR(buf + offset, t[1]); \
} while (0) offset += (uint32)sizeof(uint64); \
} while (0)
#define EMIT_BUF(v, len) do { \ #define EMIT_BUF(v, len) \
CHECK_BUF(len); \ do { \
memcpy(buf + offset, v, len); \ CHECK_BUF(len); \
offset += len; \ memcpy(buf + offset, v, len); \
} while (0) offset += len; \
} while (0)
#define EMIT_STR(s) do { \ #define EMIT_STR(s) \
uint32 str_len = (uint32)strlen(s); \ do { \
EMIT_U16(str_len); \ uint32 str_len = (uint32)strlen(s); \
EMIT_BUF(s, str_len); \ EMIT_U16(str_len); \
} while (0) EMIT_BUF(s, str_len); \
} while (0)
static bool static bool
aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset, aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
@ -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);
@ -1563,9 +1569,9 @@ aot_emit_native_symbol(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
} }
typedef uint32 U32; typedef uint32 U32;
typedef int32 I32; typedef int32 I32;
typedef uint16 U16; typedef uint16 U16;
typedef uint8 U8; typedef uint8 U8;
struct coff_hdr { struct coff_hdr {
U16 u16Machine; U16 u16Machine;
@ -1577,35 +1583,35 @@ struct coff_hdr {
U16 u16Characs; U16 u16Characs;
}; };
#define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_IA64 0x0200 #define IMAGE_FILE_MACHINE_IA64 0x0200
#define AOT_COFF_BIN_TYPE 6 #define AOT_COFF_BIN_TYPE 6
#define EI_NIDENT 16 #define EI_NIDENT 16
typedef uint32 elf32_word; typedef uint32 elf32_word;
typedef int32 elf32_sword; typedef int32 elf32_sword;
typedef uint16 elf32_half; typedef uint16 elf32_half;
typedef uint32 elf32_off; typedef uint32 elf32_off;
typedef uint32 elf32_addr; typedef uint32 elf32_addr;
struct elf32_ehdr { struct elf32_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ident bytes */ unsigned char e_ident[EI_NIDENT]; /* ident bytes */
elf32_half e_type; /* file type */ elf32_half e_type; /* file type */
elf32_half e_machine; /* target machine */ elf32_half e_machine; /* target machine */
elf32_word e_version; /* file version */ elf32_word e_version; /* file version */
elf32_addr e_entry; /* start address */ elf32_addr e_entry; /* start address */
elf32_off e_phoff; /* phdr file offset */ elf32_off e_phoff; /* phdr file offset */
elf32_off e_shoff; /* shdr file offset */ elf32_off e_shoff; /* shdr file offset */
elf32_word e_flags; /* file flags */ elf32_word e_flags; /* file flags */
elf32_half e_ehsize; /* sizeof ehdr */ elf32_half e_ehsize; /* sizeof ehdr */
elf32_half e_phentsize; /* sizeof phdr */ elf32_half e_phentsize; /* sizeof phdr */
elf32_half e_phnum; /* number phdrs */ elf32_half e_phnum; /* number phdrs */
elf32_half e_shentsize; /* sizeof shdr */ elf32_half e_shentsize; /* sizeof shdr */
elf32_half e_shnum; /* number shdrs */ elf32_half e_shnum; /* number shdrs */
elf32_half e_shstrndx; /* shdr string index */ elf32_half e_shstrndx; /* shdr string index */
}; };
struct elf32_rel { struct elf32_rel {
@ -1619,29 +1625,29 @@ struct elf32_rela {
elf32_sword r_addend; elf32_sword r_addend;
} elf32_rela; } elf32_rela;
typedef uint32 elf64_word; typedef uint32 elf64_word;
typedef int32 elf64_sword; typedef int32 elf64_sword;
typedef uint64 elf64_xword; typedef uint64 elf64_xword;
typedef int64 elf64_sxword; typedef int64 elf64_sxword;
typedef uint16 elf64_half; typedef uint16 elf64_half;
typedef uint64 elf64_off; typedef uint64 elf64_off;
typedef uint64 elf64_addr; typedef uint64 elf64_addr;
struct elf64_ehdr { struct elf64_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ident bytes */ unsigned char e_ident[EI_NIDENT]; /* ident bytes */
elf64_half e_type; /* file type */ elf64_half e_type; /* file type */
elf64_half e_machine; /* target machine */ elf64_half e_machine; /* target machine */
elf64_word e_version; /* file version */ elf64_word e_version; /* file version */
elf64_addr e_entry; /* start address */ elf64_addr e_entry; /* start address */
elf64_off e_phoff; /* phdr file offset */ elf64_off e_phoff; /* phdr file offset */
elf64_off e_shoff; /* shdr file offset */ elf64_off e_shoff; /* shdr file offset */
elf64_word e_flags; /* file flags */ elf64_word e_flags; /* file flags */
elf64_half e_ehsize; /* sizeof ehdr */ elf64_half e_ehsize; /* sizeof ehdr */
elf64_half e_phentsize; /* sizeof phdr */ elf64_half e_phentsize; /* sizeof phdr */
elf64_half e_phnum; /* number phdrs */ elf64_half e_phnum; /* number phdrs */
elf64_half e_shentsize; /* sizeof shdr */ elf64_half e_shentsize; /* sizeof shdr */
elf64_half e_shnum; /* number shdrs */ elf64_half e_shnum; /* number shdrs */
elf64_half e_shstrndx; /* shdr string index */ elf64_half e_shstrndx; /* shdr string index */
}; };
typedef struct elf64_rel { typedef struct elf64_rel {
@ -1655,14 +1661,14 @@ 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)
static bool static bool
aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
@ -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));
@ -1774,7 +1777,7 @@ aot_resolve_text(AOTObjectData *obj_data)
return false; return false;
} }
while ( while (
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { !LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
if ((name = (char *)LLVMGetSectionName(sec_itr)) if ((name = (char *)LLVMGetSectionName(sec_itr))
&& !strcmp(name, ".text")) { && !strcmp(name, ".text")) {
obj_data->text = (char *)LLVMGetSectionContents(sec_itr); obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
@ -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,10 +2178,8 @@ 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, sec_itr)) {
relocation_group,
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

@ -23,25 +23,25 @@ int_cond_to_llvm_op(IntCond cond, LLVMIntPredicate *op)
case INT_LT_S: case INT_LT_S:
*op = LLVMIntSLT; *op = LLVMIntSLT;
break; break;
case INT_LT_U: case INT_LT_U:
*op = LLVMIntULT; *op = LLVMIntULT;
break; break;
case INT_GT_S: case INT_GT_S:
*op = LLVMIntSGT; *op = LLVMIntSGT;
break; break;
case INT_GT_U: case INT_GT_U:
*op = LLVMIntUGT; *op = LLVMIntUGT;
break; break;
case INT_LE_S: case INT_LE_S:
*op = LLVMIntSLE; *op = LLVMIntSLE;
break; break;
case INT_LE_U: case INT_LE_U:
*op = LLVMIntULE; *op = LLVMIntULE;
break; break;
case INT_GE_S: case INT_GE_S:
*op = LLVMIntSGE; *op = LLVMIntSGE;
break; break;
case INT_GE_U: case INT_GE_U:
*op = LLVMIntUGE; *op = LLVMIntUGE;
break; break;
default: default:
@ -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,111 +5,109 @@
#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)
{ {
LLVMValueRef value = I32_CONST((uint32)i32_const); LLVMValueRef value = I32_CONST((uint32)i32_const);
CHECK_LLVM_CONST(value); CHECK_LLVM_CONST(value);
PUSH_I32(value); PUSH_I32(value);
return true; return true;
fail: fail:
return false; return false;
} }
bool bool
aot_compile_op_i64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_i64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
int64 i64_const) int64 i64_const)
{ {
LLVMValueRef value = I64_CONST((uint64)i64_const); LLVMValueRef value = I64_CONST((uint64)i64_const);
CHECK_LLVM_CONST(value); CHECK_LLVM_CONST(value);
PUSH_I64(value); PUSH_I64(value);
return true; return true;
fail: fail:
return false; return false;
} }
bool bool
aot_compile_op_f32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
float32 f32_const) float32 f32_const)
{ {
LLVMValueRef alloca, value; LLVMValueRef alloca, value;
if (!isnan(f32_const)) { if (!isnan(f32_const)) {
value = F32_CONST(f32_const); value = F32_CONST(f32_const);
CHECK_LLVM_CONST(value); CHECK_LLVM_CONST(value);
PUSH_F32(value); PUSH_F32(value);
} }
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;
} }
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) { if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
} }
PUSH_F32(value); PUSH_F32(value);
} }
return true; return true;
fail: fail:
return false; return false;
} }
bool bool
aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
float64 f64_const) float64 f64_const)
{ {
LLVMValueRef alloca, value; LLVMValueRef alloca, value;
if (!isnan(f64_const)) { if (!isnan(f64_const)) {
value = F64_CONST(f64_const); value = F64_CONST(f64_const);
CHECK_LLVM_CONST(value); CHECK_LLVM_CONST(value);
PUSH_F64(value); PUSH_F64(value);
} }
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;
} }
value = I64_CONST((uint64)i64_const); value = I64_CONST((uint64)i64_const);
CHECK_LLVM_CONST(value); CHECK_LLVM_CONST(value);
if (!LLVMBuildStore(comp_ctx->builder, value, alloca)) { if (!LLVMBuildStore(comp_ctx->builder, value, 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, 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;
} }
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) { if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
aot_set_last_error("llvm build load failed."); aot_set_last_error("llvm build load failed.");
return false; return false;
} }
PUSH_F64(value); PUSH_F64(value);
} }
return true; return true;
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,34 +15,33 @@
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)
#define CURR_BLOCK() LLVMGetInsertBlock(comp_ctx->builder) #define CURR_BLOCK() LLVMGetInsertBlock(comp_ctx->builder)
@ -55,76 +54,79 @@ 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) \
if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \ do { \
aot_set_last_error("llvm build br failed."); \ if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
goto fail; \ aot_set_last_error("llvm build br failed."); \
} \ 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, \
aot_set_last_error("llvm build cond br failed."); \ block_else)) { \
goto fail; \ aot_set_last_error("llvm build cond br failed."); \
} \ goto fail; \
} while (0) } \
} while (0)
#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) \
if (block->result_count && !block->result_phis) { \ do { \
uint32 i; \ if (block->result_count && !block->result_phis) { \
uint64 size; \ uint32 i; \
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \ uint64 size; \
/* Allocate memory */ \ LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
size = sizeof(LLVMValueRef) * (uint64)block->result_count; \ /* Allocate memory */ \
if (size >= UINT32_MAX \ size = sizeof(LLVMValueRef) * (uint64)block->result_count; \
|| !(block->result_phis = \ if (size >= UINT32_MAX \
wasm_runtime_malloc((uint32)size))) { \ || !(block->result_phis = \
aot_set_last_error("allocate memory failed."); \ wasm_runtime_malloc((uint32)size))) { \
goto fail; \ aot_set_last_error("allocate memory failed."); \
} \ goto fail; \
SET_BUILDER_POS(block->llvm_end_block); \ } \
for (i = 0; i < block->result_count; i++) { \ SET_BUILDER_POS(block->llvm_end_block); \
if (!(block->result_phis[i] = \ for (i = 0; i < block->result_count; i++) { \
LLVMBuildPhi(comp_ctx->builder, \ if (!(block->result_phis[i] = LLVMBuildPhi( \
TO_LLVM_TYPE(block->result_types[i]), \ comp_ctx->builder, \
"phi"))) { \ TO_LLVM_TYPE(block->result_types[i]), "phi"))) { \
aot_set_last_error("llvm build phi failed."); \ aot_set_last_error("llvm build phi failed."); \
goto fail; \ goto fail; \
} \ } \
} \ } \
SET_BUILDER_POS(block_curr); \ SET_BUILDER_POS(block_curr); \
} \ } \
} while (0) } while (0)
#define ADD_TO_RESULT_PHIS(block, value, idx) do { \ #define ADD_TO_RESULT_PHIS(block, value, idx) \
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \ do { \
LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \ LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
LLVMTypeRef value_ty = LLVMTypeOf(value); \ LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \ LLVMTypeRef value_ty = LLVMTypeOf(value); \
bh_assert(LLVMGetTypeContext(phi_ty) \ bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
== LLVMGetTypeContext(value_ty)); \ bh_assert(LLVMGetTypeContext(phi_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 = \
aot_set_last_error("llvm build icmp failed."); \ LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
goto fail; \ aot_set_last_error("llvm build icmp failed."); \
} \ goto fail; \
} while (0) } \
} while (0)
#define ADD_TO_PARAM_PHIS(block, value, idx) do { \ #define ADD_TO_PARAM_PHIS(block, value, idx) \
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \ do { \
LLVMAddIncoming(block->param_phis[idx], \ LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
&value, &block_curr, 1); \ LLVMAddIncoming(block->param_phis[idx], &value, &block_curr, 1); \
} while (0) } while (0)
static LLVMBasicBlockRef static LLVMBasicBlockRef
find_next_llvm_end_block(AOTBlock *block) find_next_llvm_end_block(AOTBlock *block)
@ -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;
@ -172,12 +173,10 @@ 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,9 +235,9 @@ 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;
} }
@ -250,7 +248,7 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
if (block->result_count) { if (block->result_count) {
/* Return the first return value */ /* Return the first return value */
if (!(ret = if (!(ret =
LLVMBuildRet(comp_ctx->builder, block->result_phis[0]))) { LLVMBuildRet(comp_ctx->builder, block->result_phis[0]))) {
aot_set_last_error("llvm build return failed."); aot_set_last_error("llvm build return 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);
@ -678,22 +673,20 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
offset = I32_FIVE; offset = I32_FIVE;
if (!(terminate_addr = if (!(terminate_addr =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env, LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
&offset, 1, "terminate_addr"))) { &offset, 1, "terminate_addr"))) {
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(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,17 +978,17 @@ 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)))
MOVE_BLOCK_BEFORE(target_block->llvm_end_block, MOVE_BLOCK_BEFORE(target_block->llvm_end_block,
next_llvm_end_block); next_llvm_end_block);
} }
/* 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.");
@ -1061,8 +1051,8 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (!target_block) if (!target_block)
return false; return false;
target_llvm_block = target_block->label_type != LABEL_TYPE_LOOP target_llvm_block = target_block->label_type != LABEL_TYPE_LOOP
? target_block->llvm_end_block ? target_block->llvm_end_block
: target_block->llvm_entry_block; : target_block->llvm_entry_block;
LLVMAddCase(value_switch, value_case, target_llvm_block); LLVMAddCase(value_switch, value_case, target_llvm_block);
} }
@ -1101,9 +1091,8 @@ 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,24 +11,24 @@
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;
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) { comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) {
LLVMTypeRef param_types[3]; LLVMTypeRef param_types[3];
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_UNO, true); LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_UNO, true);
param_types[0] = I32_TYPE; param_types[0] = I32_TYPE;
param_types[1] = src_type; param_types[1] = src_type;
param_types[2] = src_type; param_types[2] = src_type;
res = aot_call_llvm_intrinsic( res = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp", comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
I32_TYPE, param_types, 3, opcond, operand, operand); I32_TYPE, param_types, 3, opcond, operand, operand);
if (!res) { if (!res) {
goto fail; goto fail;
} }
@ -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,26 +53,27 @@ 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
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) { comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) {
LLVMTypeRef param_types[3]; LLVMTypeRef param_types[3];
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_LE, true); LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_LE, true);
param_types[0] = I32_TYPE; param_types[0] = I32_TYPE;
param_types[1] = src_type; param_types[1] = src_type;
param_types[2] = src_type; param_types[2] = src_type;
is_less = aot_call_llvm_intrinsic( is_less = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp", comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
I32_TYPE, param_types, 3, opcond, operand, min_value); I32_TYPE, param_types, 3, opcond, operand, min_value);
if (!is_less) { if (!is_less) {
goto fail; goto fail;
} }
is_less = is_less =
LLVMBuildIntCast(comp_ctx->builder, is_less, INT1_TYPE, "bit_cast"); LLVMBuildIntCast(comp_ctx->builder, is_less, INT1_TYPE, "bit_cast");
} }
else { else {
is_less = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLE, operand, is_less = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLE, operand,
@ -88,15 +87,15 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) { comp_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp")) {
LLVMTypeRef param_types[3]; LLVMTypeRef param_types[3];
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_GE, true); LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_GE, true);
param_types[0] = I32_TYPE; param_types[0] = I32_TYPE;
param_types[1] = src_type; param_types[1] = src_type;
param_types[2] = src_type; param_types[2] = src_type;
is_greater = aot_call_llvm_intrinsic( is_greater = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp", comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
I32_TYPE, param_types, 3, opcond, operand, max_value); I32_TYPE, param_types, 3, opcond, operand, max_value);
if (!is_greater) { if (!is_greater) {
goto fail; goto fail;
} }
@ -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) \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ do { \
func_ctx->func, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
name))) { \ func_ctx->func, 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;
@ -573,12 +571,13 @@ aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
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_TYPE, param_types, 1, value); : "f32_convert_i32_u",
F32_TYPE, param_types, 1, value);
} }
else { else {
if (sign) if (sign)
@ -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;
@ -609,12 +608,13 @@ aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
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_TYPE, param_types, 1, value); : "f32_convert_i64_u",
F32_TYPE, param_types, 1, value);
} }
else { else {
if (sign) if (sign)
@ -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;
@ -676,13 +677,14 @@ aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
comp_ctx, sign ? "f64_convert_i32_s" : "f64_convert_i32_u")) { comp_ctx, sign ? "f64_convert_i32_s" : "f64_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 ? "f64_convert_i32_s" : "f64_convert_i32_u", sign ? "f64_convert_i32_s"
F64_TYPE, param_types, 1, value); : "f64_convert_i32_u",
F64_TYPE, param_types, 1, value);
} }
else { else {
if (sign) if (sign)
@ -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;
@ -714,13 +716,14 @@ aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ct
if (comp_ctx->disable_llvm_intrinsics if (comp_ctx->disable_llvm_intrinsics
&& aot_intrinsic_check_capability( && aot_intrinsic_check_capability(
comp_ctx, sign ? "f64_convert_i64_s" : "f64_convert_i64_u")) { comp_ctx, sign ? "f64_convert_i64_s" : "f64_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 ? "f64_convert_i64_s" : "f64_convert_i64_u", sign ? "f64_convert_i64_s"
F64_TYPE, param_types, 1, value); : "f64_convert_i64_u",
F64_TYPE, param_types, 1, value);
} }
else { else {
if (sign) if (sign)
@ -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;
} }
@ -37,7 +33,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Create exection id phi */ /* Create exection id phi */
if (!(func_ctx->exception_id_phi = LLVMBuildPhi( if (!(func_ctx->exception_id_phi = LLVMBuildPhi(
comp_ctx->builder, I32_TYPE, "exception_id_phi"))) { comp_ctx->builder, I32_TYPE, "exception_id_phi"))) {
aot_set_last_error("llvm build phi failed."); aot_set_last_error("llvm build phi 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;
} }
@ -62,7 +57,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
/* Create LLVM function with const function pointer */ /* Create LLVM function with const function pointer */
if (!(func_const = if (!(func_const =
I64_CONST((uint64)(uintptr_t)aot_set_exception_with_id)) I64_CONST((uint64)(uintptr_t)aot_set_exception_with_id))
|| !(func = LLVMConstIntToPtr(func_const, func_ptr_type))) { || !(func = LLVMConstIntToPtr(func_const, func_ptr_type))) {
aot_set_last_error("create LLVM value failed."); aot_set_last_error("create LLVM value failed.");
return false; return false;
@ -76,13 +71,13 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
func_index = aot_get_native_symbol_index( func_index = aot_get_native_symbol_index(
comp_ctx, "aot_set_exception_with_id"); comp_ctx, "aot_set_exception_with_id");
if (func_index < 0) { if (func_index < 0) {
return false; return false;
} }
if (!(func = if (!(func =
aot_get_func_from_table(comp_ctx, func_ctx->native_symbol, aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
func_ptr_type, func_index))) { func_ptr_type, func_index))) {
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,14 +9,14 @@
#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) \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ do { \
func_ctx->func, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
name))) { \ func_ctx->func, 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)
static bool static bool
create_func_return_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) create_func_return_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
@ -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;
@ -145,11 +144,12 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 i, cell_num = 0; uint32 i, cell_num = 0;
/* prepare function type of aot_invoke_native */ /* prepare function type of aot_invoke_native */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
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;
} }
@ -187,7 +186,7 @@ call_aot_invoke_native_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 = && !(func =
LLVMAddFunction(comp_ctx->module, 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;
} }
@ -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 =
ret_ptr_type, "argv_ret"))) { LLVMBuildBitCast(comp_ctx->builder, func_ctx->argv_buf,
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.");
@ -498,7 +493,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
for (i = 0; i < ext_ret_count; i++) { for (i = 0; i < ext_ret_count; i++) {
if (!(ext_ret_idx = I32_CONST(cell_num)) if (!(ext_ret_idx = I32_CONST(cell_num))
|| !(ext_ret_ptr_type = || !(ext_ret_ptr_type =
LLVMPointerType(TO_LLVM_TYPE(ext_ret_types[i]), 0))) { LLVMPointerType(TO_LLVM_TYPE(ext_ret_types[i]), 0))) {
aot_set_last_error("llvm add const or pointer type failed."); aot_set_last_error("llvm add const or pointer type failed.");
goto fail; goto fail;
} }
@ -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;
@ -657,12 +656,13 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 i, cell_num = 0, ret_cell_num, argv_cell_num; uint32 i, cell_num = 0, ret_cell_num, argv_cell_num;
/* prepare function type of aot_call_indirect */ /* prepare function type of aot_call_indirect */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
func_param_types[1] = I32_TYPE; /* table_idx */ func_param_types[1] = I32_TYPE; /* table_idx */
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,38 +847,35 @@ 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;
} }
if (!(table_size_const = if (!(table_size_const =
LLVMBuildBitCast(comp_ctx->builder, table_size_const, LLVMBuildBitCast(comp_ctx->builder, table_size_const,
INT32_PTR_TYPE, "cur_siuze_i32p"))) { INT32_PTR_TYPE, "cur_siuze_i32p"))) {
HANDLE_FAILURE("LLVMBuildBitCast"); HANDLE_FAILURE("LLVMBuildBitCast");
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,17 +972,17 @@ 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;
total_size = sizeof(LLVMTypeRef) * (uint64)total_param_count; total_size = sizeof(LLVMTypeRef) * (uint64)total_param_count;
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
@ -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,25 +1038,24 @@ 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;
} }
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,14 +1184,16 @@ 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
/* Reserve some local variables */ + 1
+ 16)) /* Reserve some local variables */
+ 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 =
&func_idx, 1, "func_ptr_tmp"))) { LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs,
&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 = \
aot_set_last_error("llvm build icmp failed."); \ LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
goto fail; \ aot_set_last_error("llvm build icmp failed."); \
} \ 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) \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ do { \
func_ctx->func, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
name))) { \ func_ctx->func, 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);
@ -103,20 +101,20 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
|| is_shared_memory || is_shared_memory
#endif #endif
) { ) {
mem_base_addr = func_ctx->mem_info[0].mem_base_addr; mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
} }
else { else {
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.");
goto fail; goto fail;
} }
} }
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,12 +134,12 @@ 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 =
comp_ctx->comp_data->memories[0].mem_init_page_count; comp_ctx->comp_data->memories[0].mem_init_page_count;
uint64 mem_data_size = num_bytes_per_page * init_page_count; uint64 mem_data_size = num_bytes_per_page * init_page_count;
if (mem_offset + bytes <= mem_data_size) { if (mem_offset + bytes <= mem_data_size) {
@ -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;
} }
@ -175,7 +173,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
&& aot_checked_addr_list_find(func_ctx, local_idx_of_aot_value, && aot_checked_addr_list_find(func_ctx, local_idx_of_aot_value,
offset, bytes))) { offset, bytes))) {
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;
if (init_page_count == 0) { if (init_page_count == 0) {
LLVMValueRef mem_size; LLVMValueRef mem_size;
@ -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;
} }
@ -196,7 +194,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
if (!(mem_check_bound = if (!(mem_check_bound =
get_memory_check_bound(comp_ctx, func_ctx, bytes))) { get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
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,55 +238,60 @@ 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, \
aot_set_last_error("llvm build bit cast failed."); \ "data_ptr"))) { \
goto fail; \ aot_set_last_error("llvm build bit cast failed."); \
} \ 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, \
aot_set_last_error("llvm build trunc failed."); \ "val_trunc"))) { \
goto fail; \ aot_set_last_error("llvm build trunc failed."); \
} \ goto fail; \
} while (0) } \
} while (0)
#define BUILD_STORE() do { \ #define BUILD_STORE() \
LLVMValueRef res; \ do { \
if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \ LLVMValueRef res; \
aot_set_last_error("llvm build store failed."); \ if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \
goto fail; \ aot_set_last_error("llvm build store failed."); \
} \ goto fail; \
LLVMSetAlignment(res, 1); \ } \
} while (0) LLVMSetAlignment(res, 1); \
} 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, \
aot_set_last_error("llvm build sign ext failed."); \ "data_s_ext"))) { \
goto fail; \ aot_set_last_error("llvm build sign ext failed."); \
} \ 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, \
aot_set_last_error("llvm build zero ext failed."); \ "data_z_ext"))) { \
goto fail; \ aot_set_last_error("llvm build zero ext failed."); \
} \ goto fail; \
} while (0) } \
} while (0)
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
bool bool
@ -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,39 +332,40 @@ fail:
return false; return false;
} }
#define BUILD_ATOMIC_LOAD(align) do { \ #define BUILD_ATOMIC_LOAD(align) \
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \ do { \
goto fail; \ if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
} \ goto fail; \
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, \ } \
"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 << align); \ LLVMSetAlignment(value, 1 << align); \
LLVMSetVolatile(value, true); \ LLVMSetVolatile(value, true); \
LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \ LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \
} while (0) } while (0)
#define BUILD_ATOMIC_STORE(align) do { \ #define BUILD_ATOMIC_STORE(align) \
LLVMValueRef res; \ do { \
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \ LLVMValueRef res; \
goto fail; \ if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
} \ goto fail; \
if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \ } \
aot_set_last_error("llvm build store failed."); \ if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \
goto fail; \ aot_set_last_error("llvm build store failed."); \
} \ goto fail; \
LLVMSetAlignment(res, 1 << align); \ } \
LLVMSetVolatile(res, true); \ LLVMSetAlignment(res, 1 << align); \
LLVMSetOrdering(res, LLVMAtomicOrderingSequentiallyConsistent); \ LLVMSetVolatile(res, true); \
} while (0) LLVMSetOrdering(res, LLVMAtomicOrderingSequentiallyConsistent); \
} while (0)
#endif #endif
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;
} }
@ -694,7 +696,7 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
return false; return false;
} }
func_index = func_index =
aot_get_native_symbol_index(comp_ctx, "aot_enlarge_memory"); aot_get_native_symbol_index(comp_ctx, "aot_enlarge_memory");
if (func_index < 0) { if (func_index < 0) {
return false; return false;
} }
@ -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,10 +764,9 @@ 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.");
goto fail; goto fail;
} }
@ -785,16 +785,14 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(offset); uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(offset);
uint64 mem_len = (uint64)LLVMConstIntGetZExtValue(bytes); uint64 mem_len = (uint64)LLVMConstIntGetZExtValue(bytes);
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 =
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,10 +805,9 @@ 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.");
goto fail; goto fail;
} }
@ -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,14 +886,14 @@ 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;
} }
/* If memory.init failed, return this function /* If memory.init failed, return this function
so the runtime can catch the exception */ so the runtime can catch the exception */
LLVMPositionBuilderAtEnd(comp_ctx->builder, mem_init_fail); LLVMPositionBuilderAtEnd(comp_ctx->builder, mem_init_fail);
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)) {
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,25 +1034,24 @@ 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;
} }
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,34 +1110,32 @@ 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;
} }
LLVMSetVolatile(result, true); LLVMSetVolatile(result, true);
/* 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,14 +1209,13 @@ 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;
} }
/* If atomic wait failed, return this function /* If atomic wait failed, return this function
so the runtime can catch the exception */ so the runtime can catch the exception */
LLVMPositionBuilderAtEnd(comp_ctx->builder, wait_fail); LLVMPositionBuilderAtEnd(comp_ctx->builder, wait_fail);
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)) {
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_ */

File diff suppressed because it is too large Load Diff

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

@ -18,12 +18,10 @@ aot_compile_op_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
bool 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;
@ -19,9 +17,9 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx,
/* from the head of AOTModuleInstance */ /* from the head of AOTModuleInstance */
offset = offset =
offsetof(AOTModuleInstance, global_table_data.bytes) offsetof(AOTModuleInstance, global_table_data.bytes)
+ (uint64)comp_ctx->comp_data->memory_count * sizeof(AOTMemoryInstance) + (uint64)comp_ctx->comp_data->memory_count * sizeof(AOTMemoryInstance)
+ comp_ctx->comp_data->global_data_size; + comp_ctx->comp_data->global_data_size;
while (i < tbl_idx && i < comp_ctx->comp_data->import_table_count) { while (i < tbl_idx && i < comp_ctx->comp_data->import_table_count) {
offset += offsetof(AOTTableInstance, data); offset += offsetof(AOTTableInstance, data);
@ -49,14 +47,13 @@ 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;
if (!(offset = if (!(offset =
I64_CONST(get_tbl_inst_offset(comp_ctx, func_ctx, tbl_idx)))) { I64_CONST(get_tbl_inst_offset(comp_ctx, func_ctx, tbl_idx)))) {
HANDLE_FAILURE("LLVMConstInt"); HANDLE_FAILURE("LLVMConstInt");
goto fail; goto fail;
} }
@ -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;
@ -95,7 +91,7 @@ aot_compile_op_elem_drop(AOTCompContext *comp_ctx,
/* "" means return void */ /* "" means return void */
if (!(ret_value = if (!(ret_value =
LLVMBuildCall(comp_ctx->builder, func, param_values, 2, ""))) { LLVMBuildCall(comp_ctx->builder, func, param_values, 2, ""))) {
HANDLE_FAILURE("LLVMBuildCall"); HANDLE_FAILURE("LLVMBuildCall");
goto fail; goto fail;
} }
@ -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;
@ -147,7 +141,7 @@ aot_check_table_access(AOTCompContext *comp_ctx,
/* Throw exception if elem index >= table size */ /* Throw exception if elem index >= table size */
if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext( if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext(
comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) { comp_ctx->context, 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;
} }
@ -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,14 +191,14 @@ 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;
} }
if (!(func_idx = if (!(func_idx =
LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) { LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) {
HANDLE_FAILURE("LLVMBuildLoad"); HANDLE_FAILURE("LLVMBuildLoad");
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,13 +7,14 @@
#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) \
if (idx >= func_ctx->aot_func->func_type->param_count \ do { \
+ func_ctx->aot_func->local_count) { \ if (idx >= func_ctx->aot_func->func_type->param_count \
aot_set_last_error("local index out of range"); \ + func_ctx->aot_func->local_count) { \
return false; \ aot_set_last_error("local index out of range"); \
} \ return false; \
} while (0) } \
} while (0)
static uint8 static uint8
get_local_type(AOTFuncContext *func_ctx, uint32 local_idx) get_local_type(AOTFuncContext *func_ctx, uint32 local_idx)
@ -21,8 +22,8 @@ get_local_type(AOTFuncContext *func_ctx, uint32 local_idx)
AOTFunc *aot_func = func_ctx->aot_func; AOTFunc *aot_func = func_ctx->aot_func;
uint32 param_count = aot_func->func_type->param_count; uint32 param_count = aot_func->func_type->param_count;
return local_idx < param_count return local_idx < param_count
? aot_func->func_type->types[local_idx] ? aot_func->func_type->types[local_idx]
: aot_func->local_types[local_idx - param_count]; : aot_func->local_types[local_idx - param_count];
} }
bool bool
@ -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,15 +127,16 @@ 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 =
&offset, 1, "global_ptr_tmp"))) { LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&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,61 +184,56 @@ 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;
} }
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,163 +33,162 @@
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
*/ */
typedef struct AOTValue { typedef struct AOTValue {
struct AOTValue *next; struct AOTValue *next;
struct AOTValue *prev; struct AOTValue *prev;
LLVMValueRef value; LLVMValueRef value;
/* VALUE_TYPE_I32/I64/F32/F64/VOID */ /* VALUE_TYPE_I32/I64/F32/F64/VOID */
uint8 type; uint8 type;
bool is_local; bool is_local;
uint32 local_idx; uint32 local_idx;
} AOTValue; } AOTValue;
/** /**
* Value stack, represents stack elements in a WASM block * Value stack, represents stack elements in a WASM block
*/ */
typedef struct AOTValueStack { typedef struct AOTValueStack {
AOTValue *value_list_head; AOTValue *value_list_head;
AOTValue *value_list_end; AOTValue *value_list_end;
} AOTValueStack; } AOTValueStack;
typedef struct AOTBlock { typedef struct AOTBlock {
struct AOTBlock *next; struct AOTBlock *next;
struct AOTBlock *prev; struct AOTBlock *prev;
/* Block index */ /* Block index */
uint32 block_index; uint32 block_index;
/* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */ /* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
uint32 label_type; uint32 label_type;
/* Whether it is reachable */ /* Whether it is reachable */
bool is_reachable; bool is_reachable;
/* Whether skip translation of wasm else branch */ /* Whether skip translation of wasm else branch */
bool skip_wasm_code_else; bool skip_wasm_code_else;
/* code of else opcode of this block, if it is a IF block */ /* code of else opcode of this block, if it is a IF block */
uint8 *wasm_code_else; uint8 *wasm_code_else;
/* code end of this block */ /* code end of this block */
uint8 *wasm_code_end; uint8 *wasm_code_end;
/* LLVM label points to code begin */ /* LLVM label points to code begin */
LLVMBasicBlockRef llvm_entry_block; LLVMBasicBlockRef llvm_entry_block;
/* LLVM label points to code else */ /* LLVM label points to code else */
LLVMBasicBlockRef llvm_else_block; LLVMBasicBlockRef llvm_else_block;
/* LLVM label points to code end */ /* LLVM label points to code end */
LLVMBasicBlockRef llvm_end_block; LLVMBasicBlockRef llvm_end_block;
/* WASM operation stack */ /* WASM operation stack */
AOTValueStack value_stack; AOTValueStack value_stack;
/* Param count/types/PHIs of this block */ /* Param count/types/PHIs of this block */
uint32 param_count; uint32 param_count;
uint8 *param_types; uint8 *param_types;
LLVMValueRef *param_phis; LLVMValueRef *param_phis;
LLVMValueRef *else_param_phis; LLVMValueRef *else_param_phis;
/* Result count/types/PHIs of this block */ /* Result count/types/PHIs of this block */
uint32 result_count; uint32 result_count;
uint8 *result_types; uint8 *result_types;
LLVMValueRef *result_phis; LLVMValueRef *result_phis;
} AOTBlock; } AOTBlock;
/** /**
* Block stack, represents WASM block stack elements * Block stack, represents WASM block stack elements
*/ */
typedef struct AOTBlockStack { typedef struct AOTBlockStack {
AOTBlock *block_list_head; AOTBlock *block_list_head;
AOTBlock *block_list_end; AOTBlock *block_list_end;
/* Current block index of each block type */ /* Current block index of each block type */
uint32 block_index[3]; uint32 block_index[3];
} AOTBlockStack; } AOTBlockStack;
typedef struct AOTCheckedAddr { typedef struct AOTCheckedAddr {
struct AOTCheckedAddr *next; struct AOTCheckedAddr *next;
uint32 local_idx; uint32 local_idx;
uint32 offset; uint32 offset;
uint32 bytes; uint32 bytes;
} AOTCheckedAddr, *AOTCheckedAddrList; } AOTCheckedAddr, *AOTCheckedAddrList;
typedef struct AOTMemInfo { typedef struct AOTMemInfo {
LLVMValueRef mem_base_addr; LLVMValueRef mem_base_addr;
LLVMValueRef mem_data_size_addr; LLVMValueRef mem_data_size_addr;
LLVMValueRef mem_cur_page_count_addr; LLVMValueRef mem_cur_page_count_addr;
LLVMValueRef mem_bound_check_1byte; LLVMValueRef mem_bound_check_1byte;
LLVMValueRef mem_bound_check_2bytes; LLVMValueRef mem_bound_check_2bytes;
LLVMValueRef mem_bound_check_4bytes; LLVMValueRef mem_bound_check_4bytes;
LLVMValueRef mem_bound_check_8bytes; LLVMValueRef mem_bound_check_8bytes;
LLVMValueRef mem_bound_check_16bytes; LLVMValueRef mem_bound_check_16bytes;
} AOTMemInfo; } AOTMemInfo;
typedef struct AOTFuncContext { typedef struct AOTFuncContext {
AOTFunc *aot_func; AOTFunc *aot_func;
LLVMValueRef func; LLVMValueRef func;
LLVMTypeRef func_type; LLVMTypeRef func_type;
AOTBlockStack block_stack; AOTBlockStack block_stack;
LLVMValueRef exec_env; LLVMValueRef exec_env;
LLVMValueRef aot_inst; LLVMValueRef aot_inst;
LLVMValueRef argv_buf; LLVMValueRef argv_buf;
LLVMValueRef native_stack_bound; LLVMValueRef native_stack_bound;
LLVMValueRef aux_stack_bound; LLVMValueRef aux_stack_bound;
LLVMValueRef aux_stack_bottom; LLVMValueRef aux_stack_bottom;
LLVMValueRef native_symbol; LLVMValueRef native_symbol;
LLVMValueRef last_alloca; LLVMValueRef last_alloca;
LLVMValueRef func_ptrs; LLVMValueRef func_ptrs;
AOTMemInfo *mem_info; AOTMemInfo *mem_info;
LLVMValueRef cur_exception; LLVMValueRef cur_exception;
bool mem_space_unchanged; bool mem_space_unchanged;
AOTCheckedAddrList checked_addr_list; AOTCheckedAddrList checked_addr_list;
LLVMBasicBlockRef got_exception_block; LLVMBasicBlockRef got_exception_block;
LLVMBasicBlockRef func_return_block; LLVMBasicBlockRef func_return_block;
LLVMValueRef exception_id_phi; LLVMValueRef exception_id_phi;
LLVMValueRef func_type_indexes; LLVMValueRef func_type_indexes;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
LLVMMetadataRef debug_func; LLVMMetadataRef debug_func;
#endif #endif
LLVMValueRef locals[1]; LLVMValueRef locals[1];
} AOTFuncContext; } AOTFuncContext;
typedef struct AOTLLVMTypes { typedef struct AOTLLVMTypes {
LLVMTypeRef int1_type; LLVMTypeRef int1_type;
LLVMTypeRef int8_type; LLVMTypeRef int8_type;
LLVMTypeRef int16_type; LLVMTypeRef int16_type;
LLVMTypeRef int32_type; LLVMTypeRef int32_type;
LLVMTypeRef int64_type; LLVMTypeRef int64_type;
LLVMTypeRef float32_type; LLVMTypeRef float32_type;
LLVMTypeRef float64_type; LLVMTypeRef float64_type;
LLVMTypeRef void_type; LLVMTypeRef void_type;
LLVMTypeRef int8_ptr_type; LLVMTypeRef int8_ptr_type;
LLVMTypeRef int8_pptr_type; LLVMTypeRef int8_pptr_type;
LLVMTypeRef int16_ptr_type; LLVMTypeRef int16_ptr_type;
LLVMTypeRef int32_ptr_type; LLVMTypeRef int32_ptr_type;
LLVMTypeRef int64_ptr_type; LLVMTypeRef int64_ptr_type;
LLVMTypeRef float32_ptr_type; LLVMTypeRef float32_ptr_type;
LLVMTypeRef float64_ptr_type; LLVMTypeRef float64_ptr_type;
LLVMTypeRef v128_type; LLVMTypeRef v128_type;
LLVMTypeRef v128_ptr_type; LLVMTypeRef v128_ptr_type;
LLVMTypeRef i8x16_vec_type; LLVMTypeRef i8x16_vec_type;
LLVMTypeRef i16x8_vec_type; LLVMTypeRef i16x8_vec_type;
LLVMTypeRef i32x4_vec_type; LLVMTypeRef i32x4_vec_type;
LLVMTypeRef i64x2_vec_type; LLVMTypeRef i64x2_vec_type;
LLVMTypeRef f32x4_vec_type; LLVMTypeRef f32x4_vec_type;
LLVMTypeRef f64x2_vec_type; LLVMTypeRef f64x2_vec_type;
LLVMTypeRef i1x2_vec_type; LLVMTypeRef i1x2_vec_type;
LLVMTypeRef meta_data_type; LLVMTypeRef meta_data_type;
LLVMTypeRef funcref_type; LLVMTypeRef funcref_type;
LLVMTypeRef externref_type; LLVMTypeRef externref_type;
} AOTLLVMTypes; } AOTLLVMTypes;
typedef struct AOTLLVMConsts { typedef struct AOTLLVMConsts {
@ -245,89 +244,89 @@ typedef struct AOTLLVMConsts {
* Compiler context * Compiler context
*/ */
typedef struct AOTCompContext { typedef struct AOTCompContext {
AOTCompData *comp_data; AOTCompData *comp_data;
/* LLVM variables required to emit LLVM IR */ /* LLVM variables required to emit LLVM IR */
LLVMContextRef context; LLVMContextRef context;
LLVMModuleRef module; LLVMModuleRef module;
LLVMBuilderRef builder; LLVMBuilderRef builder;
#if WASM_ENABLE_DEBUG_AOT #if WASM_ENABLE_DEBUG_AOT
LLVMDIBuilderRef debug_builder; LLVMDIBuilderRef debug_builder;
LLVMMetadataRef debug_file; LLVMMetadataRef debug_file;
LLVMMetadataRef debug_comp_unit; LLVMMetadataRef debug_comp_unit;
#endif #endif
LLVMTargetMachineRef target_machine; LLVMTargetMachineRef target_machine;
char *target_cpu; char *target_cpu;
char target_arch[16]; char target_arch[16];
unsigned pointer_size; unsigned pointer_size;
/* Hardware intrinsic compability flags */ /* Hardware intrinsic compability flags */
uint64 flags[8]; uint64 flags[8];
/* LLVM execution engine required by JIT */ /* LLVM execution engine required by JIT */
#if WASM_ENABLE_LAZY_JIT != 0 #if WASM_ENABLE_LAZY_JIT != 0
LLVMOrcLLLazyJITRef lazy_orcjit; LLVMOrcLLLazyJITRef lazy_orcjit;
LLVMOrcThreadSafeContextRef ts_context; LLVMOrcThreadSafeContextRef ts_context;
LLVMOrcJITTargetMachineBuilderRef tm_builder; LLVMOrcJITTargetMachineBuilderRef tm_builder;
#else #else
LLVMExecutionEngineRef exec_engine; LLVMExecutionEngineRef exec_engine;
#endif #endif
bool is_jit_mode; bool is_jit_mode;
/* AOT indirect mode flag & symbol list */ /* AOT indirect mode flag & symbol list */
bool is_indirect_mode; bool is_indirect_mode;
bh_list native_symbols; bh_list native_symbols;
/* Bulk memory feature */ /* Bulk memory feature */
bool enable_bulk_memory; bool enable_bulk_memory;
/* Bounday Check */ /* Bounday Check */
bool enable_bound_check; bool enable_bound_check;
/* 128-bit SIMD */ /* 128-bit SIMD */
bool enable_simd; bool enable_simd;
/* Auxiliary stack overflow/underflow check */ /* Auxiliary stack overflow/underflow check */
bool enable_aux_stack_check; bool enable_aux_stack_check;
/* Generate auxiliary stack frame */ /* Generate auxiliary stack frame */
bool enable_aux_stack_frame; bool enable_aux_stack_frame;
/* Thread Manager */ /* Thread Manager */
bool enable_thread_mgr; bool enable_thread_mgr;
/* Tail Call */ /* Tail Call */
bool enable_tail_call; bool enable_tail_call;
/* Reference Types */ /* Reference Types */
bool enable_ref_types; bool enable_ref_types;
/* Disable LLVM built-in intrinsics */ /* Disable LLVM built-in intrinsics */
bool disable_llvm_intrinsics; bool disable_llvm_intrinsics;
/* Whether optimize the JITed code */ /* Whether optimize the JITed code */
bool optimize; bool optimize;
/* LLVM pass manager to optimize the JITed code */ /* LLVM pass manager to optimize the JITed code */
LLVMPassManagerRef pass_mgr; LLVMPassManagerRef pass_mgr;
/* LLVM floating-point rounding mode metadata */ /* LLVM floating-point rounding mode metadata */
LLVMValueRef fp_rounding_mode; LLVMValueRef fp_rounding_mode;
/* LLVM floating-point exception behavior metadata */ /* LLVM floating-point exception behavior metadata */
LLVMValueRef fp_exception_behavior; LLVMValueRef fp_exception_behavior;
/* LLVM data types */ /* LLVM data types */
AOTLLVMTypes basic_types; AOTLLVMTypes basic_types;
LLVMTypeRef exec_env_type; LLVMTypeRef exec_env_type;
LLVMTypeRef aot_inst_type; LLVMTypeRef aot_inst_type;
/* LLVM const values */ /* LLVM const values */
AOTLLVMConsts llvm_consts; AOTLLVMConsts llvm_consts;
/* Function contexts */ /* Function contexts */
AOTFuncContext **func_ctxes; AOTFuncContext **func_ctxes;
uint32 func_ctx_count; uint32 func_ctx_count;
} AOTCompContext; } AOTCompContext;
enum { enum {
@ -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,8 +65,9 @@ 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 =
"frame-pointer", Value); Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
"frame-pointer", Value);
F.setAttributes(Attrs); F.setAttributes(Attrs);
} }
} }
@ -88,15 +86,15 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
EngineBuilder builder(std::move(Mod)); EngineBuilder builder(std::move(Mod));
builder.setEngineKind(EngineKind::JIT) builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error) .setErrorStr(&Error)
.setMCPU(mcpu) .setMCPU(mcpu)
.setOptLevel((CodeGenOpt::Level)options.OptLevel) .setOptLevel((CodeGenOpt::Level)options.OptLevel)
.setTargetOptions(targetOptions); .setTargetOptions(targetOptions);
if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT)) if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
builder.setCodeModel(*CM); builder.setCodeModel(*CM);
if (options.MCJMM) if (options.MCJMM)
builder.setMCJITMemoryManager( builder.setMCJITMemoryManager(
std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM))); std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
if (ExecutionEngine *JIT = builder.create()) { if (ExecutionEngine *JIT = builder.create()) {
*OutJIT = wrap(JIT); *OutJIT = wrap(JIT);
return 0; return 0;
@ -116,16 +114,16 @@ aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
llvm::SmallVector<std::string, 1> targetAttributes; llvm::SmallVector<std::string, 1> targetAttributes;
llvm::Triple targetTriple(arch_c_str, "", ""); llvm::Triple targetTriple(arch_c_str, "", "");
auto targetMachine = auto targetMachine =
std::unique_ptr<llvm::TargetMachine>(llvm::EngineBuilder().selectTarget( std::unique_ptr<llvm::TargetMachine>(llvm::EngineBuilder().selectTarget(
targetTriple, "", std::string(cpu_c_str), targetAttributes)); targetTriple, "", std::string(cpu_c_str), targetAttributes));
if (!targetMachine) { if (!targetMachine) {
return false; return false;
} }
const llvm::Triple::ArchType targetArch = const llvm::Triple::ArchType targetArch =
targetMachine->getTargetTriple().getArch(); targetMachine->getTargetTriple().getArch();
const llvm::MCSubtargetInfo *subTargetInfo = const llvm::MCSubtargetInfo *subTargetInfo =
targetMachine->getMCSubtargetInfo(); targetMachine->getMCSubtargetInfo();
if (subTargetInfo == nullptr) { if (subTargetInfo == nullptr) {
return false; return false;
} }
@ -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,31 +28,30 @@
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;
} dwar_extractor; } dwar_extractor;
#define TO_HANDLE(extractor) (dwar_extractor_handle_t)(extractor) #define TO_HANDLE(extractor) (dwar_extractor_handle_t)(extractor)
#define TO_EXTACTOR(handle) (dwar_extractor *)(handle) #define TO_EXTACTOR(handle) (dwar_extractor *)(handle)
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;
} }
@ -74,7 +73,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char * file_name)
} }
extractor->target = extractor->debugger.CreateTarget( extractor->target = extractor->debugger.CreateTarget(
file_name, arch, platform, false, error); file_name, arch, platform, false, error);
if (!error.Success()) { if (!error.Success()) {
LOG_ERROR("Create Dwarf target failed:%s", error.GetCString()); LOG_ERROR("Create Dwarf target failed:%s", error.GetCString());
@ -89,7 +88,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char * file_name)
extractor->module = extractor->target.FindModule(exe_file_spec); extractor->module = extractor->target.FindModule(exe_file_spec);
comp_data->extractor = TO_HANDLE(extractor); comp_data->extractor = TO_HANDLE(extractor);
return TO_HANDLE(extractor); return TO_HANDLE(extractor);
fail1: fail1:
SBDebugger::Destroy(extractor->debugger); SBDebugger::Destroy(extractor->debugger);
@ -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,30 +203,26 @@ 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(
comp_ctx->debug_builder, LLDB_TO_LLVM_LANG_TYPE(lang_type), comp_ctx->debug_builder, LLDB_TO_LLVM_LANG_TYPE(lang_type),
comp_ctx->debug_file, "ant compiler", 12, 0, NULL, 0, 1, NULL, 0, comp_ctx->debug_file, "ant compiler", 12, 0, NULL, 0, 1, NULL, 0,
LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0); LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
} }
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()) {
} }
} }
} }
@ -236,42 +230,41 @@ dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset)
static LLVMDWARFTypeEncoding 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; case eBasicTypeSignedChar:
case eBasicTypeSignedChar: encoding = llvm::dwarf::DW_ATE_signed_char;
encoding = llvm::dwarf::DW_ATE_signed_char; break;
break; case eBasicTypeUnsignedInt:
case eBasicTypeUnsignedInt: case eBasicTypeUnsignedLong:
case eBasicTypeUnsignedLong: case eBasicTypeUnsignedLongLong:
case eBasicTypeUnsignedLongLong: case eBasicTypeUnsignedWChar:
case eBasicTypeUnsignedWChar: case eBasicTypeUnsignedInt128:
case eBasicTypeUnsignedInt128: case eBasicTypeUnsignedShort:
case eBasicTypeUnsignedShort: encoding = llvm::dwarf::DW_ATE_unsigned;
encoding = llvm::dwarf::DW_ATE_unsigned; break;
break; case eBasicTypeInt:
case eBasicTypeInt: case eBasicTypeLong:
case eBasicTypeLong: case eBasicTypeLongLong:
case eBasicTypeLongLong: case eBasicTypeWChar:
case eBasicTypeWChar: case eBasicTypeInt128:
case eBasicTypeInt128: case eBasicTypeShort:
case eBasicTypeShort: encoding = llvm::dwarf::DW_ATE_signed;
encoding = llvm::dwarf::DW_ATE_signed; break;
break; case eBasicTypeBool:
case eBasicTypeBool: encoding = llvm::dwarf::DW_ATE_boolean;
encoding = llvm::dwarf::DW_ATE_boolean; break;
break; case eBasicTypeHalf:
case eBasicTypeHalf: case eBasicTypeFloat:
case eBasicTypeFloat: case eBasicTypeDouble:
case eBasicTypeDouble: case eBasicTypeLongDouble:
case eBasicTypeLongDouble: encoding = llvm::dwarf::DW_ATE_float;
encoding = llvm::dwarf::DW_ATE_float; break;
break; default:
default: break;
break;
} }
return encoding; return encoding;
} }
@ -288,21 +281,22 @@ lldb_type_to_type_dbi(AOTCompContext *comp_ctx, SBType &type)
if (basic_type != eBasicTypeInvalid) { if (basic_type != eBasicTypeInvalid) {
encoding = lldb_get_basic_type_encoding(basic_type); encoding = lldb_get_basic_type_encoding(basic_type);
type_info = LLVMDIBuilderCreateBasicType( type_info = LLVMDIBuilderCreateBasicType(
DIB, type.GetName(), strlen(type.GetName()), bit_size, encoding, DIB, type.GetName(), strlen(type.GetName()), bit_size, encoding,
LLVMDIFlagZero); LLVMDIFlagZero);
} }
else if (type.IsPointerType()) { else if (type.IsPointerType()) {
SBType pointee_type = type.GetPointeeType(); SBType pointee_type = type.GetPointeeType();
type_info = LLVMDIBuilderCreatePointerType( type_info = LLVMDIBuilderCreatePointerType(
DIB, lldb_type_to_type_dbi(comp_ctx, pointee_type), bit_size, 0, 0, DIB, lldb_type_to_type_dbi(comp_ctx, pointee_type), bit_size, 0, 0,
"", 0); "", 0);
} }
return type_info; return type_info;
} }
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();
@ -314,14 +308,12 @@ 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,78 +322,81 @@ 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 =
LLVMDIBuilderCreateReplaceableCompositeType( LLVMDIBuilderCreateReplaceableCompositeType(
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());
auto valtype = variable.GetType(); auto valtype = variable.GetType();
LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation( LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
comp_ctx->context, dec.GetLine(), dec.GetColumn(), comp_ctx->context, dec.GetLine(), dec.GetColumn(),
FunctionMetadata, NULL); FunctionMetadata, NULL);
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 =
LLVMGetParam(func_ctx->func, function_arg_idx + 1); LLVMGetParam(func_ctx->func, function_arg_idx + 1);
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar, LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar,
ParamExpression, ParamLocation, ParamExpression, ParamLocation,
block_curr); block_curr);
} }
} }
return FunctionMetadata; return FunctionMetadata;
} }
@ -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,8 +515,9 @@ 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)
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset); - comp_ctx->comp_data->wasm_module->buf_code;
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset);
return location_info; return location_info;
} }

View File

@ -11,8 +11,9 @@
#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))
struct AOTCompData; struct AOTCompData;
@ -35,24 +36,21 @@ LLVMMetadataRef
dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx); dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx);
LLVMMetadataRef 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
#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,15 +69,17 @@ 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;
} }
@ -98,8 +98,8 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
param_types[0] = V128_i8x16_TYPE; param_types[0] = V128_i8x16_TYPE;
param_types[1] = V128_i8x16_TYPE; param_types[1] = V128_i8x16_TYPE;
if (!(result = aot_call_llvm_intrinsic( if (!(result = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "llvm.x86.ssse3.pshuf.b.128", V128_i8x16_TYPE, comp_ctx, func_ctx, "llvm.x86.ssse3.pshuf.b.128", V128_i8x16_TYPE,
param_types, 2, vector, mask))) { param_types, 2, vector, mask))) {
HANDLE_FAILURE("LLVMBuildCall"); HANDLE_FAILURE("LLVMBuildCall");
goto fail; goto fail;
} }
@ -122,7 +122,7 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx) AOTFuncContext *func_ctx)
{ {
LLVMValueRef vector, mask, default_lane_value, condition, max_lane_id, LLVMValueRef vector, mask, default_lane_value, condition, max_lane_id,
result, idx, id, replace_with_zero, elem, elem_or_zero, undef; result, idx, id, replace_with_zero, elem, elem_or_zero, undef;
uint8 i; uint8 i;
if (!(mask = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, V128_i8x16_TYPE, if (!(mask = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, V128_i8x16_TYPE,
@ -142,7 +142,7 @@ aot_compile_simd_swizzle_common(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_lane_id = simd_build_splat_const_integer_vector( if (!(max_lane_id = simd_build_splat_const_integer_vector(
comp_ctx, INT8_TYPE, 16, 16))) { comp_ctx, INT8_TYPE, 16, 16))) {
goto fail; goto fail;
} }
@ -152,9 +152,9 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
goto fail; goto fail;
} }
/* if the id is out of range (>=16), set the id as 0 */ /* if the id is out of range (>=16), set the id as 0 */
if (!(default_lane_value = simd_build_splat_const_integer_vector( if (!(default_lane_value = simd_build_splat_const_integer_vector(
comp_ctx, INT8_TYPE, 0, 16))) { comp_ctx, INT8_TYPE, 0, 16))) {
goto fail; goto fail;
} }
@ -172,8 +172,8 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
} }
if (!(replace_with_zero = if (!(replace_with_zero =
LLVMBuildExtractElement(comp_ctx->builder, condition, LLVMBuildExtractElement(comp_ctx->builder, condition,
I8_CONST(i), "replace_with_zero"))) { I8_CONST(i), "replace_with_zero"))) {
HANDLE_FAILURE("LLVMBuildExtractElement"); HANDLE_FAILURE("LLVMBuildExtractElement");
goto fail; goto fail;
} }
@ -185,15 +185,15 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
} }
if (!(elem_or_zero = if (!(elem_or_zero =
LLVMBuildSelect(comp_ctx->builder, replace_with_zero, LLVMBuildSelect(comp_ctx->builder, replace_with_zero,
I8_CONST(0), elem, "elem_or_zero"))) { I8_CONST(0), elem, "elem_or_zero"))) {
HANDLE_FAILURE("LLVMBuildSelect"); HANDLE_FAILURE("LLVMBuildSelect");
goto fail; goto fail;
} }
if (!(undef = if (!(undef =
LLVMBuildInsertElement(comp_ctx->builder, undef, elem_or_zero, LLVMBuildInsertElement(comp_ctx->builder, undef, elem_or_zero,
I8_CONST(i), "new_vector"))) { I8_CONST(i), "new_vector"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
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);
uint8 lane_id);
bool bool
aot_compile_simd_load8_lane(AOTCompContext *comp_ctx, aot_compile_simd_load8_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_load16_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_load32_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTFuncContext *func_ctx,
uint8 lane_id); uint8 lane_id);
bool bool
aot_compile_simd_load64_lane(AOTCompContext *comp_ctx, aot_compile_simd_load64_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_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;
} }
@ -72,15 +69,15 @@ simd_shift(AOTCompContext *comp_ctx,
/* splat to a vector */ /* splat to a vector */
if (!(offset = if (!(offset =
LLVMBuildInsertElement(comp_ctx->builder, undef[itype], offset, LLVMBuildInsertElement(comp_ctx->builder, undef[itype], offset,
I32_ZERO, "offset_vector_base"))) { I32_ZERO, "offset_vector_base"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
return false; return false;
} }
if (!(offset = if (!(offset =
LLVMBuildShuffleVector(comp_ctx->builder, offset, undef[itype], LLVMBuildShuffleVector(comp_ctx->builder, offset, undef[itype],
mask[itype], "offset_vector"))) { mask[itype], "offset_vector"))) {
HANDLE_FAILURE("LLVMBuildShuffleVector"); HANDLE_FAILURE("LLVMBuildShuffleVector");
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

@ -47,8 +47,8 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
/* fill every bit in a lange with its sign bit */ /* fill every bit in a lange with its sign bit */
if (!(ashr_distance = simd_build_splat_const_integer_vector( if (!(ashr_distance = simd_build_splat_const_integer_vector(
comp_ctx, element_type[itype], lane_bits[itype] - 1, comp_ctx, element_type[itype], lane_bits[itype] - 1,
lanes[itype]))) { lanes[itype]))) {
goto fail; goto fail;
} }
@ -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,25 +74,25 @@ 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;
} }
if (!(vector = if (!(vector =
LLVMBuildAnd(comp_ctx->builder, vector, mask, "mask_bits"))) { LLVMBuildAnd(comp_ctx->builder, vector, mask, "mask_bits"))) {
HANDLE_FAILURE("LLVMBuildAnd"); HANDLE_FAILURE("LLVMBuildAnd");
goto fail; goto fail;
} }
if (!(result = if (!(result =
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype], aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
I64_TYPE, &vector_ext_type, 1, vector))) { I64_TYPE, &vector_ext_type, 1, vector))) {
goto fail; goto fail;
} }
if (!(result = if (!(result =
LLVMBuildTrunc(comp_ctx->builder, result, I32_TYPE, "to_i32"))) { LLVMBuildTrunc(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
HANDLE_FAILURE("LLVMBuildTrunc"); HANDLE_FAILURE("LLVMBuildTrunc");
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;
@ -27,7 +26,7 @@ v128_bitwise_two_component(AOTCompContext *comp_ctx,
break; break;
case V128_OR: case V128_OR:
if (!(result = if (!(result =
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "or"))) { LLVMBuildOr(comp_ctx->builder, vector1, vector2, "or"))) {
HANDLE_FAILURE("LLVMBuildAnd"); HANDLE_FAILURE("LLVMBuildAnd");
goto fail; goto fail;
} }
@ -95,7 +94,7 @@ v128_bitwise_bitselect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
POP_V128(vector1); POP_V128(vector1);
if (!(vector1 = if (!(vector1 =
LLVMBuildAnd(comp_ctx->builder, vector1, vector3, "a_and_c"))) { LLVMBuildAnd(comp_ctx->builder, vector1, vector3, "a_and_c"))) {
HANDLE_FAILURE("LLVMBuildAdd"); HANDLE_FAILURE("LLVMBuildAdd");
goto fail; goto fail;
} }
@ -106,13 +105,13 @@ v128_bitwise_bitselect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
} }
if (!(vector2 = if (!(vector2 =
LLVMBuildAnd(comp_ctx->builder, vector2, vector3, "b_and_c"))) { LLVMBuildAnd(comp_ctx->builder, vector2, vector3, "b_and_c"))) {
HANDLE_FAILURE("LLVMBuildAdd"); HANDLE_FAILURE("LLVMBuildAdd");
goto fail; goto fail;
} }
if (!(result = if (!(result =
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "a_or_b"))) { LLVMBuildOr(comp_ctx->builder, vector1, vector2, "a_or_b"))) {
HANDLE_FAILURE("LLVMBuildOr"); HANDLE_FAILURE("LLVMBuildOr");
goto fail; goto fail;
} }
@ -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,14 +55,14 @@ 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;
} }
if (!(result = if (!(result =
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) { LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
HANDLE_FAILURE("LLVMBuildZExt"); HANDLE_FAILURE("LLVMBuildZExt");
goto fail; goto fail;
} }
@ -120,13 +119,13 @@ aot_compile_simd_v128_any_true(AOTCompContext *comp_ctx,
} }
if (!(result = aot_call_llvm_intrinsic( if (!(result = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "llvm.vector.reduce.or.v128i1", INT1_TYPE, comp_ctx, func_ctx, "llvm.vector.reduce.or.v128i1", INT1_TYPE,
&vector_type, 1, vector))) { &vector_type, 1, vector))) {
goto fail; goto fail;
} }
if (!(result = if (!(result =
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) { LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
HANDLE_FAILURE("LLVMBuildZExt"); HANDLE_FAILURE("LLVMBuildZExt");
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;
@ -16,7 +15,7 @@ simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
POP_V128(number); POP_V128(number);
if (!(number = if (!(number =
LLVMBuildBitCast(comp_ctx->builder, number, vec_type, name))) { LLVMBuildBitCast(comp_ctx->builder, number, vec_type, name))) {
HANDLE_FAILURE("LLVMBuildBitCast"); HANDLE_FAILURE("LLVMBuildBitCast");
goto fail; goto fail;
} }
@ -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;
@ -79,7 +76,7 @@ simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (!(elements[i] = if (!(elements[i] =
LLVMConstInt(element_type, element_value[i], true))) { LLVMConstInt(element_type, element_value[i], true))) {
HANDLE_FAILURE("LLVMConstInst"); HANDLE_FAILURE("LLVMConstInst");
goto fail; goto fail;
} }
@ -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;
@ -110,14 +108,14 @@ interger_vector_compare(AOTCompContext *comp_ctx,
} }
/* icmp <N x iX> %vec1, %vec2 */ /* icmp <N x iX> %vec1, %vec2 */
if (!(result = if (!(result =
LLVMBuildICmp(comp_ctx->builder, int_pred, vec1, vec2, "cmp"))) { LLVMBuildICmp(comp_ctx->builder, int_pred, vec1, vec2, "cmp"))) {
HANDLE_FAILURE("LLVMBuildICmp"); HANDLE_FAILURE("LLVMBuildICmp");
goto fail; goto fail;
} }
/* sext <N x i1> %result to <N x iX> */ /* sext <N x i1> %result to <N x iX> */
if (!(result = if (!(result =
LLVMBuildSExt(comp_ctx->builder, result, vector_type, "ext"))) { LLVMBuildSExt(comp_ctx->builder, result, vector_type, "ext"))) {
HANDLE_FAILURE("LLVMBuildSExt"); HANDLE_FAILURE("LLVMBuildSExt");
goto fail; goto fail;
} }
@ -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;
@ -194,14 +186,14 @@ float_vector_compare(AOTCompContext *comp_ctx,
} }
/* fcmp <N x iX> %vec1, %vec2 */ /* fcmp <N x iX> %vec1, %vec2 */
if (!(result = if (!(result =
LLVMBuildFCmp(comp_ctx->builder, real_pred, vec1, vec2, "cmp"))) { LLVMBuildFCmp(comp_ctx->builder, real_pred, vec1, vec2, "cmp"))) {
HANDLE_FAILURE("LLVMBuildFCmp"); HANDLE_FAILURE("LLVMBuildFCmp");
goto fail; goto fail;
} }
/* sext <N x i1> %result to <N x iX> */ /* sext <N x i1> %result to <N x iX> */
if (!(result = if (!(result =
LLVMBuildSExt(comp_ctx->builder, result, result_type, "ext"))) { LLVMBuildSExt(comp_ctx->builder, result, result_type, "ext"))) {
HANDLE_FAILURE("LLVMBuildSExt"); HANDLE_FAILURE("LLVMBuildSExt");
goto fail; goto fail;
} }
@ -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;
@ -26,8 +25,8 @@ aot_compile_simd_v128_const(AOTCompContext *comp_ctx,
} }
if (!(agg1 = if (!(agg1 =
LLVMBuildInsertElement(comp_ctx->builder, LLVM_CONST(i64x2_undef), LLVMBuildInsertElement(comp_ctx->builder, LLVM_CONST(i64x2_undef),
first_long, I32_ZERO, "agg1"))) { first_long, I32_ZERO, "agg1"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
goto fail; goto fail;
} }
@ -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) {
@ -75,7 +72,7 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
POP_I32(input); POP_I32(input);
/* trunc i32 %input to i8 */ /* trunc i32 %input to i8 */
value = value =
LLVMBuildTrunc(comp_ctx->builder, input, INT8_TYPE, "trunc"); LLVMBuildTrunc(comp_ctx->builder, input, INT8_TYPE, "trunc");
break; break;
} }
case SIMD_i16x8_splat: case SIMD_i16x8_splat:
@ -84,7 +81,7 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
POP_I32(input); POP_I32(input);
/* trunc i32 %input to i16 */ /* trunc i32 %input to i16 */
value = value =
LLVMBuildTrunc(comp_ctx->builder, input, INT16_TYPE, "trunc"); LLVMBuildTrunc(comp_ctx->builder, input, INT16_TYPE, "trunc");
break; break;
} }
case SIMD_i32x4_splat: case SIMD_i32x4_splat:
@ -118,23 +115,21 @@ 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;
} }
/* 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;
@ -101,13 +95,13 @@ simd_saturate(AOTCompContext *comp_ctx,
} }
if (!(result = aot_call_llvm_intrinsic( if (!(result = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, comp_ctx, func_ctx,
is_signed ? smin_intrinsic[itype] : umin_intrinsic[itype], is_signed ? smin_intrinsic[itype] : umin_intrinsic[itype],
param_types[itype][0], param_types[itype], 2, vector, max)) param_types[itype][0], param_types[itype], 2, vector, max))
|| !(result = aot_call_llvm_intrinsic( || !(result = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, comp_ctx, func_ctx,
is_signed ? smax_intrinsic[itype] : umax_intrinsic[itype], is_signed ? smax_intrinsic[itype] : umax_intrinsic[itype],
param_types[itype][0], param_types[itype], 2, result, min))) { param_types[itype][0], param_types[itype], 2, result, min))) {
return NULL; return NULL;
} }
@ -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,17 +144,17 @@ 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;
} }
if (!(max = simd_build_splat_const_integer_vector( if (!(max = simd_build_splat_const_integer_vector(
comp_ctx, min_max_type[itype], comp_ctx, min_max_type[itype],
is_signed ? smax[itype] : umax[itype], length[itype])) is_signed ? smax[itype] : umax[itype], length[itype]))
|| !(min = simd_build_splat_const_integer_vector( || !(min = simd_build_splat_const_integer_vector(
comp_ctx, min_max_type[itype], comp_ctx, min_max_type[itype],
is_signed ? smin[itype] : umin[itype], length[itype]))) { is_signed ? smin[itype] : umin[itype], length[itype]))) {
return false; return false;
} }
@ -200,14 +192,13 @@ 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(
comp_ctx, func_ctx, V128_i16x8_TYPE, V128_i8x16_TYPE, comp_ctx, func_ctx, V128_i16x8_TYPE, V128_i8x16_TYPE,
is_signed ? "llvm.x86.sse2.packsswb.128" is_signed ? "llvm.x86.sse2.packsswb.128"
: "llvm.x86.sse2.packuswb.128"); : "llvm.x86.sse2.packuswb.128");
} }
else { else {
return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i16x8, return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i16x8,
@ -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;
@ -425,7 +403,7 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
V128_f64x2_TYPE, out_vector_type))) { V128_f64x2_TYPE, out_vector_type))) {
return false; return false;
} }
if (!(zero = LLVMConstNull(out_vector_type))) { if (!(zero = LLVMConstNull(out_vector_type))) {
HANDLE_FAILURE("LLVMConstNull"); HANDLE_FAILURE("LLVMConstNull");
return false; return false;
@ -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,14 +503,12 @@ 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,
result; result;
LLVMValueRef even_element[] = { LLVMValueRef even_element[] = {
LLVM_CONST(i32_zero), LLVM_CONST(i32_two), LLVM_CONST(i32_four), LLVM_CONST(i32_zero), LLVM_CONST(i32_two), LLVM_CONST(i32_four),
@ -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;
} }
@ -567,9 +539,9 @@ simd_extadd_pairwise(AOTCompContext *comp_ctx,
/* shuffle a <16xi8> vector to two <8xi8> vectors */ /* shuffle a <16xi8> vector to two <8xi8> vectors */
if (!(sub_vector_even = LLVMBuildShuffleVector( if (!(sub_vector_even = LLVMBuildShuffleVector(
comp_ctx->builder, vector, vector, even_mask, "pick_even")) comp_ctx->builder, vector, vector, even_mask, "pick_even"))
|| !(sub_vector_odd = LLVMBuildShuffleVector( || !(sub_vector_odd = LLVMBuildShuffleVector(
comp_ctx->builder, vector, vector, odd_mask, "pick_odd"))) { comp_ctx->builder, vector, vector, odd_mask, "pick_odd"))) {
HANDLE_FAILURE("LLVMBuildShuffleVector"); HANDLE_FAILURE("LLVMBuildShuffleVector");
return false; return false;
} }
@ -577,22 +549,22 @@ simd_extadd_pairwise(AOTCompContext *comp_ctx,
/* sext/zext <8xi8> to <8xi16> */ /* sext/zext <8xi8> to <8xi16> */
if (is_signed) { if (is_signed) {
if (!(sub_vector_even = if (!(sub_vector_even =
LLVMBuildSExt(comp_ctx->builder, sub_vector_even, LLVMBuildSExt(comp_ctx->builder, sub_vector_even,
out_vector_type, "even_sext")) out_vector_type, "even_sext"))
|| !(sub_vector_odd = || !(sub_vector_odd =
LLVMBuildSExt(comp_ctx->builder, sub_vector_odd, LLVMBuildSExt(comp_ctx->builder, sub_vector_odd,
out_vector_type, "odd_sext"))) { out_vector_type, "odd_sext"))) {
HANDLE_FAILURE("LLVMBuildSExt"); HANDLE_FAILURE("LLVMBuildSExt");
return false; return false;
} }
} }
else { else {
if (!(sub_vector_even = if (!(sub_vector_even =
LLVMBuildZExt(comp_ctx->builder, sub_vector_even, LLVMBuildZExt(comp_ctx->builder, sub_vector_even,
out_vector_type, "even_zext")) out_vector_type, "even_zext"))
|| !(sub_vector_odd = || !(sub_vector_odd =
LLVMBuildZExt(comp_ctx->builder, sub_vector_odd, LLVMBuildZExt(comp_ctx->builder, sub_vector_odd,
out_vector_type, "odd_zext"))) { out_vector_type, "odd_zext"))) {
HANDLE_FAILURE("LLVMBuildZExt"); HANDLE_FAILURE("LLVMBuildZExt");
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,15 +10,13 @@
#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;
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
@ -43,7 +41,7 @@ simd_v128_float_arith(AOTCompContext *comp_ctx,
if (!result) { if (!result) {
HANDLE_FAILURE( HANDLE_FAILURE(
"LLVMBuildFAdd/LLVMBuildFSub/LLVMBuildFMul/LLVMBuildFDiv"); "LLVMBuildFAdd/LLVMBuildFSub/LLVMBuildFMul/LLVMBuildFDiv");
return false; return false;
} }
@ -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,16 +216,14 @@ 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;
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
@ -252,7 +235,7 @@ simd_float_cmp(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) { LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
HANDLE_FAILURE("LLVMBuildSelect"); HANDLE_FAILURE("LLVMBuildSelect");
return false; return false;
} }
@ -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];
@ -292,15 +272,15 @@ simd_float_pmin_max(AOTCompContext *comp_ctx,
param_types[1] = vector_type; param_types[1] = vector_type;
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
} }
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,12 +333,12 @@ 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,
LLVM_CONST(i32_one), "new_vector_1"))) { LLVM_CONST(i32_one), "new_vector_1"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
return false; return false;
} }
@ -381,27 +359,27 @@ 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;
} }
/* fpext <f32> elem to <f64> */ /* fpext <f32> elem to <f64> */
if (!(elem_0 = if (!(elem_0 =
LLVMBuildFPExt(comp_ctx->builder, elem_0, F64_TYPE, "elem_0_ext")) LLVMBuildFPExt(comp_ctx->builder, elem_0, F64_TYPE, "elem_0_ext"))
|| !(elem_1 = LLVMBuildFPExt(comp_ctx->builder, elem_1, F64_TYPE, || !(elem_1 = LLVMBuildFPExt(comp_ctx->builder, elem_1, F64_TYPE,
"elem_1_ext"))) { "elem_1_ext"))) {
HANDLE_FAILURE("LLVMBuildFPExt"); HANDLE_FAILURE("LLVMBuildFPExt");
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,
LLVM_CONST(i32_one), "new_vector_1"))) { LLVM_CONST(i32_one), "new_vector_1"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
return false; return false;
} }

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,15 +9,13 @@
#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;
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
@ -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);
@ -84,7 +78,7 @@ simd_neg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMTypeRef type)
LLVMValueRef vector, result; LLVMValueRef vector, result;
if (!(vector = if (!(vector =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, type, "vector"))) { simd_pop_v128_and_bitcast(comp_ctx, func_ctx, type, "vector"))) {
return false; return false;
} }
@ -141,17 +135,14 @@ 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;
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
@ -170,7 +161,7 @@ simd_v128_cmp(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) { LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
HANDLE_FAILURE("LLVMBuildSelect"); HANDLE_FAILURE("LLVMBuildSelect");
return false; return false;
} }
@ -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;
@ -152,8 +140,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index], LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
element, I32_ZERO, "base"))) { element, I32_ZERO, "base"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
return false; return false;
} }
@ -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;
@ -188,7 +173,7 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
bh_assert(opcode_index < 4); bh_assert(opcode_index < 4);
if (!(vector = simd_pop_v128_and_bitcast( if (!(vector = simd_pop_v128_and_bitcast(
comp_ctx, func_ctx, vector_types[opcode_index], "src"))) { comp_ctx, func_ctx, vector_types[opcode_index], "src"))) {
return false; return false;
} }
@ -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;
@ -242,8 +224,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
} }
if (!(result = if (!(result =
LLVMBuildInsertElement(comp_ctx->builder, undef[opcode_index], LLVMBuildInsertElement(comp_ctx->builder, undef[opcode_index],
element, I32_ZERO, "vector"))) { element, I32_ZERO, "vector"))) {
HANDLE_FAILURE("LLVMBuildInsertElement"); HANDLE_FAILURE("LLVMBuildInsertElement");
return false; return false;
} }
@ -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;
@ -333,7 +306,7 @@ aot_compile_simd_store_lane(AOTCompContext *comp_ctx,
bh_assert(opcode_index < 4); bh_assert(opcode_index < 4);
if (!(vector = simd_pop_v128_and_bitcast( if (!(vector = simd_pop_v128_and_bitcast(
comp_ctx, func_ctx, vector_types[opcode_index], "src"))) { comp_ctx, func_ctx, vector_types[opcode_index], "src"))) {
return false; return false;
} }

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,16 +9,14 @@
#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];
if (!(rhs = if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) { "lhs"))) {
return false; return false;
@ -28,8 +26,8 @@ simd_sat_int_arith(AOTCompContext *comp_ctx,
param_types[1] = vector_type; param_types[1] = vector_type;
if (!(result = if (!(result =
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsics, aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsics,
vector_type, param_types, 2, lhs, rhs))) { vector_type, param_types, 2, lhs, rhs))) {
HANDLE_FAILURE("LLVMBuildCall"); HANDLE_FAILURE("LLVMBuildCall");
return false; return false;
} }
@ -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,14 +59,13 @@ 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);
control_thread->server = control_thread->server =
wasm_launch_gdbserver(control_thread->ip_addr, control_thread->port); wasm_launch_gdbserver(control_thread->ip_addr, control_thread->port);
if (!control_thread->server) { if (!control_thread->server) {
LOG_ERROR("Failed to create debug server\n"); LOG_ERROR("Failed to create debug server\n");
os_cond_signal(&exec_env->wait_cond); os_cond_signal(&exec_env->wait_cond);
@ -110,7 +109,7 @@ wasm_debug_control_thread_create(WASMDebugInstance *debug_instance)
bh_assert(exec_env); bh_assert(exec_env);
if (!(control_thread = if (!(control_thread =
wasm_runtime_malloc(sizeof(WASMDebugControlThread)))) { wasm_runtime_malloc(sizeof(WASMDebugControlThread)))) {
LOG_ERROR("WASM Debug Engine error: failed to allocate memory"); LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
return NULL; return NULL;
} }
@ -123,8 +122,9 @@ 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
debug_instance, APP_THREAD_STACK_SIZE_MAX)) { != os_thread_create(&control_thread->tid, control_thread_routine,
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);
@ -200,9 +199,9 @@ wasm_debug_engine_init(char *ip_addr, int platform_port, int process_port)
if (g_debug_engine) { if (g_debug_engine) {
process_port -= 1; process_port -= 1;
g_debug_engine->platform_port = g_debug_engine->platform_port =
platform_port > 0 ? platform_port : 1234; platform_port > 0 ? platform_port : 1234;
g_debug_engine->process_base_port = g_debug_engine->process_base_port =
process_port > 0 ? process_port : 6169; process_port > 0 ? process_port : 6169;
if (ip_addr) if (ip_addr)
sprintf(g_debug_engine->ip_addr, "%s", ip_addr); sprintf(g_debug_engine->ip_addr, "%s", ip_addr);
else else
@ -277,7 +276,7 @@ static WASMDebugInstance *
wasm_cluster_get_debug_instance(WASMDebugEngine *engine, WASMCluster *cluster) wasm_cluster_get_debug_instance(WASMDebugEngine *engine, WASMCluster *cluster)
{ {
WASMDebugInstance *instance = WASMDebugInstance *instance =
bh_list_first_elem(&engine->debug_instance_list); bh_list_first_elem(&engine->debug_instance_list);
while (instance) { while (instance) {
if (instance->cluster == cluster) if (instance->cluster == cluster)
return instance; return instance;
@ -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,13 +452,12 @@ 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(
WasmObj, instance->id, WasmObj, instance->id,
(exec_env->cur_frame->ip - module_inst->module->load_addr)); (exec_env->cur_frame->ip - module_inst->module->load_addr));
} }
return 0; return 0;
} }
@ -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;
@ -567,14 +565,14 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
if (offset + *size > module_inst->module->load_size) { if (offset + *size > module_inst->module->load_size) {
LOG_VERBOSE("wasm_debug_instance_get_data_mem size over flow!\n"); LOG_VERBOSE("wasm_debug_instance_get_data_mem size over flow!\n");
*size = module_inst->module->load_size >= offset *size = module_inst->module->load_size >= offset
? module_inst->module->load_size - offset ? module_inst->module->load_size - offset
: 0; : 0;
} }
bh_memcpy_s(buf, *size, module_inst->module->load_addr + offset, *size); bh_memcpy_s(buf, *size, module_inst->module->load_addr + offset, *size);
WASMDebugBreakPoint *breakpoint = WASMDebugBreakPoint *breakpoint =
bh_list_first_elem(&instance->break_point_list); bh_list_first_elem(&instance->break_point_list);
while (breakpoint) { while (breakpoint) {
if (offset <= breakpoint->addr && breakpoint->addr < offset + *size) { if (offset <= breakpoint->addr && breakpoint->addr < offset + *size) {
@ -585,12 +583,12 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
} }
WASMFastOPCodeNode *fast_opcode = WASMFastOPCodeNode *fast_opcode =
bh_list_first_elem(&module_inst->module->fast_opcode_list); bh_list_first_elem(&module_inst->module->fast_opcode_list);
while (fast_opcode) { while (fast_opcode) {
if (offset <= fast_opcode->offset if (offset <= fast_opcode->offset
&& fast_opcode->offset < offset + *size) { && fast_opcode->offset < offset + *size) {
*(uint8 *)(buf + (fast_opcode->offset - offset)) = *(uint8 *)(buf + (fast_opcode->offset - offset)) =
fast_opcode->orig_op; fast_opcode->orig_op;
} }
fast_opcode = bh_list_elem_next(fast_opcode); fast_opcode = bh_list_elem_next(fast_opcode);
} }
@ -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,17 +661,17 @@ 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:
return wasm_debug_instance_get_linear_mem( return wasm_debug_instance_get_linear_mem(
instance, WASM_ADDR_OFFSET(addr), buf, size); instance, WASM_ADDR_OFFSET(addr), buf, size);
break; break;
case WasmObj: case WasmObj:
return wasm_debug_instance_get_obj_mem( return wasm_debug_instance_get_obj_mem(
instance, WASM_ADDR_OFFSET(addr), buf, size); instance, WASM_ADDR_OFFSET(addr), buf, size);
break; break;
default: default:
return false; return false;
@ -683,13 +679,13 @@ 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:
return wasm_debug_instance_set_linear_mem( return wasm_debug_instance_set_linear_mem(
instance, WASM_ADDR_OFFSET(addr), buf, size); instance, WASM_ADDR_OFFSET(addr), buf, size);
break; break;
case WasmObj: case WasmObj:
default: default:
@ -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;
@ -727,13 +723,13 @@ wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
while (exec_env) { while (exec_env) {
if (exec_env->handle == tid) { if (exec_env->handle == tid) {
WASMModuleInstance *module_inst = WASMModuleInstance *module_inst =
(WASMModuleInstance *)exec_env->module_inst; (WASMModuleInstance *)exec_env->module_inst;
frame = exec_env->cur_frame; frame = exec_env->cur_frame;
while (frame && i < size) { while (frame && i < size) {
if (frame->ip != NULL) { if (frame->ip != NULL) {
buf[i++] = buf[i++] =
WASM_ADDR(WasmObj, instance->id, WASM_ADDR(WasmObj, instance->id,
(frame->ip - module_inst->module->load_addr)); (frame->ip - module_inst->module->load_addr));
} }
frame = frame->prev_frame; frame = frame->prev_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;
@ -769,23 +765,20 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
if (offset + sizeof(break_instr) <= module_inst->module->load_size) { if (offset + sizeof(break_instr) <= module_inst->module->load_size) {
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;
@ -819,10 +812,9 @@ wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance,
if (length >= sizeof(break_instr)) { if (length >= sizeof(break_instr)) {
if (offset + sizeof(break_instr) <= module_inst->module->load_size) { if (offset + sizeof(break_instr) <= module_inst->module->load_size) {
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;
@ -1003,9 +993,9 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance,
global_addr = global_data + global->data_offset; global_addr = global_data + global->data_offset;
#else #else
global_addr = global->import_global_inst global_addr = global->import_global_inst
? global->import_module_inst->global_data ? global->import_module_inst->global_data
+ global->import_global_inst->data_offset + global->import_global_inst->data_offset
: global_data + global->data_offset; : global_data + global->data_offset;
#endif #endif
global_type = global->type; global_type = global->type;
@ -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

@ -67,10 +67,10 @@ typedef enum WasmAddressType {
WasmInvalid = 0x03 WasmInvalid = 0x03
} WasmAddressType; } WasmAddressType;
#define WASM_ADDR(type, id, offset) \ #define WASM_ADDR(type, id, offset) \
(((uint64)type << 62) | ((uint64)0 << 32) | ((uint64)offset << 0)) (((uint64)type << 62) | ((uint64)0 << 32) | ((uint64)offset << 0))
#define WASM_ADDR_TYPE(addr) (((addr)&0xC000000000000000) >> 62) #define WASM_ADDR_TYPE(addr) (((addr)&0xC000000000000000) >> 62)
#define WASM_ADDR_OFFSET(addr) (((addr)&0x00000000FFFFFFFF)) #define WASM_ADDR_OFFSET(addr) (((addr)&0x00000000FFFFFFFF))
#define INVALIED_ADDR (0xFFFFFFFFFFFFFFFF) #define INVALIED_ADDR (0xFFFFFFFFFFFFFFFF)
@ -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,13 +55,13 @@ 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
char objname[128]; char objname[128];
wasm_debug_instance_get_current_object_name( wasm_debug_instance_get_current_object_name(
(WASMDebugInstance *)server->thread->debug_instance, objname, 128); (WASMDebugInstance *)server->thread->debug_instance, objname, 128);
sprintf(tmpbuf, sprintf(tmpbuf,
"l<library-list><library name=\"%s\"><section " "l<library-list><library name=\"%s\"><section "
"address=\"0x%lx\"/></library></library-list>", "address=\"0x%lx\"/></library></library-list>",
@ -88,8 +88,8 @@ porcess_wasm_local(WASMGDBServer *server, char *args)
sprintf(tmpbuf, "E01"); sprintf(tmpbuf, "E01");
if (sscanf(args, "%d;%d", &frame_index, &local_index) == 2) { if (sscanf(args, "%d;%d", &frame_index, &local_index) == 2) {
ret = wasm_debug_instance_get_local( ret = wasm_debug_instance_get_local(
(WASMDebugInstance *)server->thread->debug_instance, frame_index, (WASMDebugInstance *)server->thread->debug_instance, frame_index,
local_index, buf, &size); local_index, buf, &size);
if (ret && size > 0) { if (ret && size > 0) {
mem2hex(buf, tmpbuf, size); mem2hex(buf, tmpbuf, size);
} }
@ -109,8 +109,8 @@ porcess_wasm_global(WASMGDBServer *server, char *args)
sprintf(tmpbuf, "E01"); sprintf(tmpbuf, "E01");
if (sscanf(args, "%d;%d", &frame_index, &global_index) == 2) { if (sscanf(args, "%d;%d", &frame_index, &global_index) == 2) {
ret = wasm_debug_instance_get_global( ret = wasm_debug_instance_get_global(
(WASMDebugInstance *)server->thread->debug_instance, frame_index, (WASMDebugInstance *)server->thread->debug_instance, frame_index,
global_index, buf, &size); global_index, buf, &size);
if (ret && size > 0) { if (ret && size > 0) {
mem2hex(buf, tmpbuf, size); mem2hex(buf, tmpbuf, size);
} }
@ -133,14 +133,15 @@ handle_generay_query(WASMGDBServer *server, char *payload)
if (!strcmp(name, "C")) { if (!strcmp(name, "C")) {
uint64_t pid, tid; uint64_t pid, tid;
pid = wasm_debug_instance_get_pid( pid = wasm_debug_instance_get_pid(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
tid = wasm_debug_instance_get_tid( tid = wasm_debug_instance_get_tid(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
snprintf(tmpbuf, sizeof(tmpbuf), "QCp%lx.%lx", pid, tid); snprintf(tmpbuf, sizeof(tmpbuf), "QCp%lx.%lx", pid, tid);
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;",
@ -200,9 +199,9 @@ handle_generay_query(WASMGDBServer *server, char *payload)
} }
if (!strcmp(name, "RegisterInfo0")) { if (!strcmp(name, "RegisterInfo0")) {
sprintf( sprintf(
tmpbuf, tmpbuf,
"name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;" "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
"set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;"); "set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
} }
else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) { else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) {
@ -215,24 +214,23 @@ handle_generay_query(WASMGDBServer *server, char *payload)
if (args && (!strcmp(name, "MemoryRegionInfo"))) { if (args && (!strcmp(name, "MemoryRegionInfo"))) {
uint64_t addr = strtol(args, NULL, 16); uint64_t addr = strtol(args, NULL, 16);
WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion( WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion(
(WASMDebugInstance *)server->thread->debug_instance, addr); (WASMDebugInstance *)server->thread->debug_instance, addr);
if (mem_info) { if (mem_info) {
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);
} }
} }
if (!strcmp(name, "WasmData")) { if (!strcmp(name, "WasmData")) {
} }
if (!strcmp(name, "WasmMem")) { if (!strcmp(name, "WasmMem")) {
} }
if (!strcmp(name, "Symbol")) { if (!strcmp(name, "Symbol")) {
@ -243,8 +241,8 @@ handle_generay_query(WASMGDBServer *server, char *payload)
uint64_t tid = strtol(args, NULL, 16); uint64_t tid = strtol(args, NULL, 16);
uint64_t buf[1024 / sizeof(uint64_t)]; uint64_t buf[1024 / sizeof(uint64_t)];
uint64_t count = wasm_debug_instance_get_call_stack_pcs( uint64_t count = wasm_debug_instance_get_call_stack_pcs(
(WASMDebugInstance *)server->thread->debug_instance, tid, buf, (WASMDebugInstance *)server->thread->debug_instance, tid, buf,
1024 / sizeof(uint64_t)); 1024 / sizeof(uint64_t));
if (count > 0) { if (count > 0) {
mem2hex((char *)buf, tmpbuf, count * sizeof(uint64_t)); mem2hex((char *)buf, tmpbuf, count * sizeof(uint64_t));
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
@ -276,16 +274,17 @@ send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
return; return;
} }
tids_number = wasm_debug_instance_get_tids( tids_number = wasm_debug_instance_get_tids(
(WASMDebugInstance *)server->thread->debug_instance, tids, 20); (WASMDebugInstance *)server->thread->debug_instance, tids, 20);
uint64_t pc = wasm_debug_instance_get_pc( uint64_t pc = wasm_debug_instance_get_pc(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
if (status == WAMR_SIG_SINGSTEP) { if (status == WAMR_SIG_SINGSTEP) {
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) {
@ -336,12 +335,12 @@ handle_v_packet(WASMGDBServer *server, char *payload)
*numstring++ = '\0'; *numstring++ = '\0';
uint64_t tid = strtol(numstring, NULL, 16); uint64_t tid = strtol(numstring, NULL, 16);
wasm_debug_instance_set_cur_thread( wasm_debug_instance_set_cur_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid); (WASMDebugInstance *)server->thread->debug_instance, tid);
wasm_debug_instance_singlestep( wasm_debug_instance_singlestep(
(WASMDebugInstance *)server->thread->debug_instance, tid); (WASMDebugInstance *)server->thread->debug_instance, tid);
tid = wasm_debug_instance_wait_thread( tid = wasm_debug_instance_wait_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid, (WASMDebugInstance *)server->thread->debug_instance, tid,
&status); &status);
send_thread_stop_status(server, status, tid); send_thread_stop_status(server, status, tid);
} }
} }
@ -352,11 +351,11 @@ void
handle_threadstop_request(WASMGDBServer *server, char *payload) handle_threadstop_request(WASMGDBServer *server, char *payload)
{ {
uint64_t tid = wasm_debug_instance_get_tid( uint64_t tid = wasm_debug_instance_get_tid(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
uint32_t status; uint32_t status;
tid = wasm_debug_instance_wait_thread( tid = wasm_debug_instance_wait_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid, &status); (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
send_thread_stop_status(server, status, tid); send_thread_stop_status(server, status, tid);
} }
@ -370,7 +369,7 @@ handle_set_current_thread(WASMGDBServer *server, char *payload)
tid = strtol(payload, NULL, 16); tid = strtol(payload, NULL, 16);
if (tid > 0) if (tid > 0)
wasm_debug_instance_set_cur_thread( wasm_debug_instance_set_cur_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid); (WASMDebugInstance *)server->thread->debug_instance, tid);
} }
write_packet(server, "OK"); write_packet(server, "OK");
} }
@ -385,7 +384,7 @@ handle_get_register(WASMGDBServer *server, char *payload)
return; return;
} }
uint64_t regdata = wasm_debug_instance_get_pc( uint64_t regdata = wasm_debug_instance_get_pc(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
mem2hex((void *)&regdata, tmpbuf, 8); mem2hex((void *)&regdata, tmpbuf, 8);
tmpbuf[8 * 2] = '\0'; tmpbuf[8 * 2] = '\0';
write_packet(server, tmpbuf); write_packet(server, tmpbuf);
@ -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");
} }
@ -470,8 +469,8 @@ handle_add_break(WASMGDBServer *server, char *payload)
if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) { if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) {
if (type == eBreakpointSoftware) { if (type == eBreakpointSoftware) {
bool ret = wasm_debug_instance_add_breakpoint( bool ret = wasm_debug_instance_add_breakpoint(
(WASMDebugInstance *)server->thread->debug_instance, addr, (WASMDebugInstance *)server->thread->debug_instance, addr,
length); length);
if (ret) if (ret)
write_packet(server, "OK"); write_packet(server, "OK");
else else
@ -490,8 +489,8 @@ handle_remove_break(WASMGDBServer *server, char *payload)
if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) { if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) {
if (type == eBreakpointSoftware) { if (type == eBreakpointSoftware) {
bool ret = wasm_debug_instance_remove_breakpoint( bool ret = wasm_debug_instance_remove_breakpoint(
(WASMDebugInstance *)server->thread->debug_instance, addr, (WASMDebugInstance *)server->thread->debug_instance, addr,
length); length);
if (ret) if (ret)
write_packet(server, "OK"); write_packet(server, "OK");
else else
@ -509,13 +508,13 @@ handle_continue_request(WASMGDBServer *server, char *payload)
uint32_t status; uint32_t status;
wasm_debug_instance_continue( wasm_debug_instance_continue(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
tid = wasm_debug_instance_get_tid( tid = wasm_debug_instance_get_tid(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
tid = wasm_debug_instance_wait_thread( tid = wasm_debug_instance_wait_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid, &status); (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
send_thread_stop_status(server, status, tid); send_thread_stop_status(server, status, tid);
} }
@ -527,13 +526,13 @@ handle_kill_request(WASMGDBServer *server, char *payload)
uint32_t status; uint32_t status;
wasm_debug_instance_kill( wasm_debug_instance_kill(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
tid = wasm_debug_instance_get_tid( tid = wasm_debug_instance_get_tid(
(WASMDebugInstance *)server->thread->debug_instance); (WASMDebugInstance *)server->thread->debug_instance);
tid = wasm_debug_instance_wait_thread( tid = wasm_debug_instance_wait_thread(
(WASMDebugInstance *)server->thread->debug_instance, tid, &status); (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
send_thread_stop_status(server, status, tid); send_thread_stop_status(server, status, tid);
} }
@ -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);
} }
@ -590,7 +590,7 @@ handle_free(WASMGDBServer *server, char *payload)
addr = strtol(payload, NULL, 16); addr = strtol(payload, NULL, 16);
ret = wasm_debug_instance_ummap( ret = wasm_debug_instance_ummap(
(WASMDebugInstance *)server->thread->debug_instance, addr); (WASMDebugInstance *)server->thread->debug_instance, addr);
if (ret) { if (ret) {
sprintf(tmpbuf, "%s", "OK"); sprintf(tmpbuf, "%s", "OK");
} }

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,13 +12,14 @@
#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)
#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)
#define get_thread_arg(exec_env) \ #define get_thread_arg(exec_env) \
wasm_exec_env_get_thread_arg(exec_env) wasm_exec_env_get_thread_arg(exec_env)
#define get_wasi_ctx(module_inst) \ #define get_wasi_ctx(module_inst) \
@ -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 {
@ -95,7 +96,7 @@ typedef struct ThreadInfoNode {
/* type can be [THREAD | MUTEX | CONDITION] */ /* type can be [THREAD | MUTEX | CONDITION] */
uint32 type; uint32 type;
/* Thread status, this variable should be volatile /* Thread status, this variable should be volatile
as its value may be changed in different threads */ as its value may be changed in different threads */
volatile uint32 status; volatile uint32 status;
bool joinable; bool joinable;
union { union {
@ -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);
} }
@ -498,8 +490,8 @@ pthread_start_routine(void *arg)
wasm_runtime_free(routine_args); wasm_runtime_free(routine_args);
/* if the thread is joinable, store the result in its info node, /* if the thread is joinable, store the result in its info node,
if the other threads join this thread after exited, then we if the other threads join this thread after exited, then we
can return the stored result */ can return the stored result */
if (!info_node->joinable) { if (!info_node->joinable) {
delete_thread_info_node(info_node); delete_thread_info_node(info_node);
} }
@ -520,10 +512,10 @@ pthread_start_routine(void *arg)
static int static int
pthread_create_wrapper(wasm_exec_env_t exec_env, pthread_create_wrapper(wasm_exec_env_t exec_env,
uint32 *thread, /* thread_handle */ uint32 *thread, /* thread_handle */
const void *attr, /* not supported */ const void *attr, /* not supported */
uint32 elem_index, /* entry function */ uint32 elem_index, /* entry function */
uint32 arg) /* arguments buffer */ uint32 arg) /* arguments buffer */
{ {
wasm_module_t module = get_module(exec_env); wasm_module_t module = get_module(exec_env);
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(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,17 +565,16 @@ 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;
} }
/* Wait for the thread routine to assign the exec_env to /* Wait for the thread routine to assign the exec_env to
thread_info_node, otherwise the exec_env in the thread thread_info_node, otherwise the exec_env in the thread
info node may be NULL in the next pthread API call */ info node may be NULL in the next pthread API call */
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock);
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
@ -618,10 +607,10 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
module_inst = get_module_inst(exec_env); module_inst = get_module_inst(exec_env);
/* validate addr, we can use current thread's /* validate addr, we can use current thread's
module instance here as the memory is shared */ module instance here as the memory is shared */
if (!validate_app_addr(retval_offset, sizeof(int32))) { if (!validate_app_addr(retval_offset, sizeof(int32))) {
/* Join failed, but we don't want to terminate all threads, /* Join failed, but we don't want to terminate all threads,
do not spread exception here */ do not spread exception here */
wasm_runtime_set_exception(module_inst, NULL); wasm_runtime_set_exception(module_inst, NULL);
return -1; return -1;
} }
@ -645,14 +634,14 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
/* if the thread has exited, return stored results */ /* if the thread has exited, return stored results */
/* this thread must be joinable, otherwise the /* this thread must be joinable, otherwise the
info_node should be destroyed once exit */ info_node should be destroyed once exit */
bh_assert(node->joinable); bh_assert(node->joinable);
join_ret = 0; join_ret = 0;
ret = node->u.ret; ret = node->u.ret;
} }
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;
} }
@ -699,7 +688,7 @@ pthread_self_wrapper(wasm_exec_env_t exec_env)
{ {
ThreadRoutineArgs *args = get_thread_arg(exec_env); ThreadRoutineArgs *args = get_thread_arg(exec_env);
/* If thread_arg is NULL, it's the exec_env of the main thread, /* If thread_arg is NULL, it's the exec_env of the main thread,
return id 0 to app */ return id 0 to app */
if (!args) if (!args)
return 0; return 0;
@ -717,8 +706,8 @@ pthread_exit_wrapper(wasm_exec_env_t exec_env, int32 retval_offset)
#if defined(OS_ENABLE_HW_BOUND_CHECK) && !defined(BH_PLATFORM_WINDOWS) #if defined(OS_ENABLE_HW_BOUND_CHECK) && !defined(BH_PLATFORM_WINDOWS)
/* If hardware bound check enabled, don't deinstantiate module inst /* If hardware bound check enabled, don't deinstantiate module inst
and thread info node here for AoT module, as they will be freed and thread info node here for AoT module, as they will be freed
in pthread_start_routine */ in pthread_start_routine */
if (exec_env->jmpbuf_stack_top) { if (exec_env->jmpbuf_stack_top) {
wasm_cluster_exit_thread(exec_env, (void *)(uintptr_t)retval_offset); wasm_cluster_exit_thread(exec_env, (void *)(uintptr_t)retval_offset);
} }
@ -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;
@ -939,7 +929,7 @@ pthread_key_create_wrapper(wasm_exec_env_t exec_env, int32 *key,
if (!info) { if (!info) {
/* The user may call pthread_key_create in main thread, /* The user may call pthread_key_create in main thread,
in this case the cluster info hasn't been created */ in this case the cluster info hasn't been created */
if (!(info = create_cluster_info(cluster))) { if (!(info = create_cluster_info(cluster))) {
return -1; return -1;
} }
@ -1037,46 +1027,50 @@ 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;
} }
#define REG_NATIVE_FUNC(func_name, signature) \ /* clang-format off */
#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"),
REG_NATIVE_FUNC(pthread_join, "(ii)i"), REG_NATIVE_FUNC(pthread_join, "(ii)i"),
REG_NATIVE_FUNC(pthread_detach, "(i)i"), REG_NATIVE_FUNC(pthread_detach, "(i)i"),
REG_NATIVE_FUNC(pthread_cancel, "(i)i"), REG_NATIVE_FUNC(pthread_cancel, "(i)i"),
REG_NATIVE_FUNC(pthread_self, "()i"), REG_NATIVE_FUNC(pthread_self, "()i"),
REG_NATIVE_FUNC(pthread_exit, "(i)"), REG_NATIVE_FUNC(pthread_exit, "(i)"),
REG_NATIVE_FUNC(pthread_mutex_init, "(**)i"), REG_NATIVE_FUNC(pthread_mutex_init, "(**)i"),
REG_NATIVE_FUNC(pthread_mutex_lock, "(*)i"), REG_NATIVE_FUNC(pthread_mutex_lock, "(*)i"),
REG_NATIVE_FUNC(pthread_mutex_unlock, "(*)i"), REG_NATIVE_FUNC(pthread_mutex_unlock, "(*)i"),
REG_NATIVE_FUNC(pthread_mutex_destroy, "(*)i"), REG_NATIVE_FUNC(pthread_mutex_destroy, "(*)i"),
REG_NATIVE_FUNC(pthread_cond_init, "(**)i"), REG_NATIVE_FUNC(pthread_cond_init, "(**)i"),
REG_NATIVE_FUNC(pthread_cond_wait, "(**)i"), REG_NATIVE_FUNC(pthread_cond_wait, "(**)i"),
REG_NATIVE_FUNC(pthread_cond_timedwait, "(**I)i"), REG_NATIVE_FUNC(pthread_cond_timedwait, "(**I)i"),
REG_NATIVE_FUNC(pthread_cond_signal, "(*)i"), REG_NATIVE_FUNC(pthread_cond_signal, "(*)i"),
REG_NATIVE_FUNC(pthread_cond_destroy, "(*)i"), REG_NATIVE_FUNC(pthread_cond_destroy, "(*)i"),
REG_NATIVE_FUNC(pthread_key_create, "(*i)i"), REG_NATIVE_FUNC(pthread_key_create, "(*i)i"),
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"), REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"), REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"), REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"), REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
}; };
uint32 uint32

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 { \
goto fail; \ if ((uint8 *)ap + _INTSIZEOF(t) > native_end_addr) \
} while (0) goto fail; \
} 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;
@ -97,14 +96,14 @@ _printf_hex_uint(out_func_t out, void *ctx,
int digits = 0; int digits = 0;
char nibble; char nibble;
while (shift >= 4) { while (shift >= 4) {
shift -= 4; shift -= 4;
nibble = (num >> shift) & 0xf; nibble = (num >> shift) & 0xf;
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;
@ -213,179 +212,188 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
} }
else { else {
switch (*fmt) { switch (*fmt) {
case '-': case '-':
padding = PAD_SPACE_AFTER; padding = PAD_SPACE_AFTER;
goto still_might_format;
case '0':
if (min_width < 0 && padding == PAD_NONE) {
padding = PAD_ZERO_BEFORE;
goto still_might_format; goto still_might_format;
case '0':
if (min_width < 0 && padding == PAD_NONE) {
padding = PAD_ZERO_BEFORE;
goto still_might_format;
}
goto handle_1_to_9;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
handle_1_to_9:
if (min_width < 0) {
min_width = *fmt - '0';
}
else {
min_width = 10 * min_width + *fmt - '0';
}
if (padding == PAD_NONE) {
padding = PAD_SPACE_BEFORE;
}
goto still_might_format;
case 'l':
long_ctr++;
/* Fall through */
case 'z':
case 'h':
/* FIXME: do nothing for these modifiers */
goto still_might_format;
case 'd':
case 'i':
{
int32 d;
if (long_ctr < 2) {
CHECK_VA_ARG(ap, int32);
d = _va_arg(ap, int32);
}
else {
int64 lld;
CHECK_VA_ARG(ap, int64);
lld = _va_arg(ap, int64);
if (lld > INT32_MAX || lld < INT32_MIN) {
print_err(out, ctx);
break;
}
d = (int32)lld;
}
if (d < 0) {
out((int)'-', ctx);
d = -d;
min_width--;
}
_printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
break;
} }
goto handle_1_to_9; case 'u':
case '1': {
case '2': uint32 u;
case '3':
case '4': if (long_ctr < 2) {
case '5': CHECK_VA_ARG(ap, uint32);
case '6': u = _va_arg(ap, uint32);
case '7': }
case '8': else {
case '9': uint64 llu;
handle_1_to_9: CHECK_VA_ARG(ap, uint64);
if (min_width < 0) { llu = _va_arg(ap, uint64);
min_width = *fmt - '0'; if (llu > INT32_MAX) {
} else { print_err(out, ctx);
min_width = 10 * min_width + *fmt - '0'; break;
}
u = (uint32)llu;
}
_printf_dec_uint(out, ctx, u, padding, min_width);
break;
}
case 'p':
out('0', ctx);
out('x', ctx);
/* left-pad pointers with zeros */
padding = PAD_ZERO_BEFORE;
min_width = 8;
/* Fall through */
case 'x':
case 'X':
{
uint64 x;
bool is_ptr = (*fmt == 'p') ? true : false;
if (long_ctr < 2) {
CHECK_VA_ARG(ap, uint32);
x = _va_arg(ap, uint32);
}
else {
CHECK_VA_ARG(ap, uint64);
x = _va_arg(ap, uint64);
}
_printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width);
break;
} }
if (padding == PAD_NONE) { case 's':
padding = PAD_SPACE_BEFORE; {
} char *s;
goto still_might_format; char *start;
uint32 s_offset;
case 'l':
long_ctr++;
/* Fall through */
case 'z':
case 'h':
/* FIXME: do nothing for these modifiers */
goto still_might_format;
case 'd':
case 'i': {
int32 d;
if (long_ctr < 2) {
CHECK_VA_ARG(ap, int32); CHECK_VA_ARG(ap, int32);
d = _va_arg(ap, int32); s_offset = _va_arg(ap, uint32);
}
else { if (!validate_app_str_addr(s_offset)) {
int64 lld; return false;
CHECK_VA_ARG(ap, int64);
lld = _va_arg(ap, int64);
if (lld > INT32_MAX || lld < INT32_MIN) {
print_err(out, ctx);
break;
} }
d = (int32)lld;
}
if (d < 0) { s = start = addr_app_to_native(s_offset);
out((int)'-', ctx);
d = -d;
min_width--;
}
_printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
break;
}
case 'u': {
uint32 u;
if (long_ctr < 2) { while (*s)
CHECK_VA_ARG(ap, uint32); out((int)(*s++), ctx);
u = _va_arg(ap, uint32);
} if (padding == PAD_SPACE_AFTER) {
else { int remaining = min_width - (int32)(s - start);
uint64 llu; while (remaining-- > 0) {
CHECK_VA_ARG(ap, uint64); out(' ', ctx);
llu = _va_arg(ap, uint64); }
if (llu > INT32_MAX) {
print_err(out, ctx);
break;
} }
u = (uint32)llu; break;
}
_printf_dec_uint(out, ctx, u, padding, min_width);
break;
}
case 'p':
out('0', ctx);
out('x', ctx);
/* left-pad pointers with zeros */
padding = PAD_ZERO_BEFORE;
min_width = 8;
/* Fall through */
case 'x':
case 'X': {
uint64 x;
bool is_ptr = (*fmt == 'p') ? true : false;
if (long_ctr < 2) {
CHECK_VA_ARG(ap, uint32);
x = _va_arg(ap, uint32);
} else {
CHECK_VA_ARG(ap, uint64);
x = _va_arg(ap, uint64);
}
_printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width);
break;
}
case 's': {
char *s;
char *start;
uint32 s_offset;
CHECK_VA_ARG(ap, int32);
s_offset = _va_arg(ap, uint32);
if (!validate_app_str_addr(s_offset)) {
return false;
} }
s = start = addr_app_to_native(s_offset); case 'c':
{
while (*s) int c;
out((int) (*s++), ctx); CHECK_VA_ARG(ap, int);
c = _va_arg(ap, int);
if (padding == PAD_SPACE_AFTER) { out(c, ctx);
int remaining = min_width - (int32)(s - start); break;
while (remaining-- > 0) {
out(' ', ctx);
}
} }
break;
}
case 'c': { case '%':
int c; {
CHECK_VA_ARG(ap, int); out((int)'%', ctx);
c = _va_arg(ap, int); break;
out(c, ctx); }
break;
}
case '%': { case 'f':
out((int) '%', ctx); {
break; float64 f64;
} char buf[16], *s;
case 'f': { /* Make 8-byte aligned */
float64 f64; ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7);
char buf[16], *s; CHECK_VA_ARG(ap, float64);
f64 = _va_arg(ap, float64);
snprintf(buf, sizeof(buf), "%f", f64);
s = buf;
while (*s)
out((int)(*s++), ctx);
break;
}
/* Make 8-byte aligned */ default:
ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7); out((int)'%', ctx);
CHECK_VA_ARG(ap, float64); out((int)*fmt, ctx);
f64 = _va_arg(ap, float64); break;
snprintf(buf, sizeof(buf), "%f", f64);
s = buf;
while (*s)
out((int) (*s++), ctx);
break;
}
default:
out((int) '%', ctx);
out((int) *fmt, ctx);
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
@ -1137,8 +1128,10 @@ 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 */
#define REG_NATIVE_FUNC(func_name, signature) \ /* clang-format off */
#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,25 +706,16 @@ 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,
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);
uvwasi_t *uvwasi = get_wasi_ctx(module_inst); uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
@ -758,8 +728,7 @@ 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_fd_readdir(uvwasi, fd, buf, buf_len, cookie, &bufused);
buf, buf_len, cookie, &bufused);
if (err) if (err)
return err; return err;
@ -768,10 +737,8 @@ 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_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
wasi_fd_t fd, uint32 path_len, char *buf, uint32 buf_len,
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);
@ -785,9 +752,8 @@ wasi_path_readlink(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_path_readlink(uvwasi, fd, err = uvwasi_path_readlink(uvwasi, fd, path, path_len, buf, buf_len,
path, path_len, &bufused);
buf, buf_len, &bufused);
if (err) if (err)
return err; return err;
@ -796,9 +762,9 @@ wasi_path_readlink(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_rename(wasm_exec_env_t exec_env, wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len, const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len) 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);
} }
#define REG_NATIVE_FUNC(func_name, signature) \ /* clang-format off */
#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;
@ -90,7 +89,7 @@ wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_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);
struct argv_environ_values *argv_environ = struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx); wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t argc, argv_buf_size, i; size_t argc, argv_buf_size, i;
char **argv; char **argv;
uint64 total_size; uint64 total_size;
@ -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;
@ -173,7 +171,7 @@ 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, /* uint32 clock_id */ wasi_clockid_t clock_id, /* uint32 clock_id */
wasi_timestamp_t precision, /* uint64 precision */ wasi_timestamp_t precision, /* uint64 precision */
wasi_timestamp_t *time /* uint64 *time */) wasi_timestamp_t *time /* uint64 *time */)
{ {
@ -186,13 +184,13 @@ 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);
struct argv_environ_values *argv_environ = struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx); wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t environ_count, environ_buf_size, i; size_t environ_count, environ_buf_size, i;
uint64 total_size; uint64 total_size;
char **environs; char **environs;
@ -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,13 +232,13 @@ 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);
struct argv_environ_values *argv_environ = struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx); wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t environ_count, environ_buf_size; size_t environ_count, environ_buf_size;
wasi_errno_t err; wasi_errno_t err;
@ -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,25 +731,17 @@ 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,
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);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -786,8 +755,7 @@ 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_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused);
buf, buf_len, cookie, &bufused);
if (err) if (err)
return err; return err;
@ -796,10 +764,8 @@ 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_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
wasi_fd_t fd, uint32 path_len, char *buf, uint32 buf_len,
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);
@ -814,9 +780,8 @@ wasi_path_readlink(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_path_readlink(curfds, fd, err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len,
path, path_len, &bufused);
buf, buf_len, &bufused);
if (err) if (err)
return err; return err;
@ -825,9 +790,9 @@ wasi_path_readlink(wasm_exec_env_t exec_env,
} }
static wasi_errno_t static wasi_errno_t
wasi_path_rename(wasm_exec_env_t exec_env, wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len, const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len) 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();
} }
#define REG_NATIVE_FUNC(func_name, signature) \ /* clang-format off */
#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
@ -32,13 +34,13 @@
#define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__)) #define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__))
#define TRYLOCKS_EXCLUSIVE(...) \ #define TRYLOCKS_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_trylock_function(__VA_ARGS__)) LOCK_ANNOTATE(exclusive_trylock_function(__VA_ARGS__))
#define TRYLOCKS_SHARED(...) LOCK_ANNOTATE(shared_trylock_function(__VA_ARGS__)) #define TRYLOCKS_SHARED(...) LOCK_ANNOTATE(shared_trylock_function(__VA_ARGS__))
#define UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__)) #define UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__))
#define REQUIRES_EXCLUSIVE(...) \ #define REQUIRES_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_locks_required(__VA_ARGS__)) LOCK_ANNOTATE(exclusive_locks_required(__VA_ARGS__))
#define REQUIRES_SHARED(...) LOCK_ANNOTATE(shared_locks_required(__VA_ARGS__)) #define REQUIRES_SHARED(...) LOCK_ANNOTATE(shared_locks_required(__VA_ARGS__))
#define REQUIRES_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__)) #define REQUIRES_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__))
@ -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
@ -12,29 +14,29 @@
#ifndef COMMON_LIMITS_H #ifndef COMMON_LIMITS_H
#define COMMON_LIMITS_H #define COMMON_LIMITS_H
#define NUMERIC_MIN(t) \ #define NUMERIC_MIN(t) \
_Generic((t)0, char \ _Generic((t)0, char \
: CHAR_MIN, signed char \ : CHAR_MIN, signed char \
: SCHAR_MIN, unsigned char : 0, short \ : SCHAR_MIN, unsigned char : 0, short \
: SHRT_MIN, unsigned short : 0, int \ : SHRT_MIN, unsigned short : 0, int \
: INT_MIN, unsigned int : 0, long \ : INT_MIN, unsigned int : 0, long \
: LONG_MIN, unsigned long : 0, long long \ : LONG_MIN, unsigned long : 0, long long \
: LLONG_MIN, unsigned long long : 0, default \ : LLONG_MIN, unsigned long long : 0, default \
: (void)0) : (void)0)
#define NUMERIC_MAX(t) \ #define NUMERIC_MAX(t) \
_Generic((t)0, char \ _Generic((t)0, char \
: CHAR_MAX, signed char \ : CHAR_MAX, signed char \
: SCHAR_MAX, unsigned char \ : SCHAR_MAX, unsigned char \
: UCHAR_MAX, short \ : UCHAR_MAX, short \
: SHRT_MAX, unsigned short \ : SHRT_MAX, unsigned short \
: USHRT_MAX, int \ : USHRT_MAX, int \
: INT_MAX, unsigned int \ : INT_MAX, unsigned int \
: UINT_MAX, long \ : UINT_MAX, long \
: LONG_MAX, unsigned long \ : LONG_MAX, unsigned long \
: ULONG_MAX, long long \ : ULONG_MAX, long long \
: LLONG_MAX, unsigned long long \ : LLONG_MAX, unsigned long long \
: ULLONG_MAX, default \ : ULLONG_MAX, default \
: (void)0) : (void)0)
#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
@ -20,41 +22,48 @@ struct fd_prestat;
struct syscalls; struct syscalls;
struct fd_table { struct fd_table {
struct rwlock lock; struct rwlock lock;
struct fd_entry *entries; struct fd_entry *entries;
size_t size; size_t size;
size_t used; size_t used;
}; };
struct fd_prestats { struct fd_prestats {
struct rwlock lock; struct rwlock lock;
struct fd_prestat *prestats; struct fd_prestat *prestats;
size_t size; size_t size;
size_t used; size_t used;
}; };
struct argv_environ_values { struct argv_environ_values {
const char *argv_buf; const char *argv_buf;
size_t argv_buf_size; size_t argv_buf_size;
char **argv_list; char **argv_list;
size_t argc; size_t argc;
char *environ_buf; char *environ_buf;
size_t environ_buf_size; size_t environ_buf_size;
char **environ_list; char **environ_list;
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
char *environ_buf, size_t environ_buf_size, fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
char **environ_list, size_t environ_count); bool
void argv_environ_destroy(struct argv_environ_values *argv_environ); argv_environ_init(struct argv_environ_values *argv_environ, char *argv_buf,
void fd_table_destroy(struct fd_table *ft); size_t argv_buf_size, char **argv_list, size_t argc,
void fd_prestats_destroy(struct fd_prestats *pt); char *environ_buf, size_t environ_buf_size,
char **environ_list, size_t environ_count);
void
argv_environ_destroy(struct argv_environ_values *argv_environ);
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
@ -15,76 +17,82 @@
// LIST: Double-linked list. // LIST: Double-linked list.
#define LIST_HEAD(name, type) \ #define LIST_HEAD(name, type) \
struct name { \ struct name { \
struct type *l_first; \ struct type *l_first; \
} }
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \ /* clang-format off */
struct { \ #define LIST_HEAD_INITIALIZER(head) \
struct type *l_next; \ { NULL }
struct type **l_prev; \ /* clang-format on */
}
#define LIST_ENTRY(type) \
struct { \
struct type *l_next; \
struct type **l_prev; \
}
#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) \
do { \ #define LIST_INIT(head) \
(head)->l_first = NULL; \ do { \
} while (0) (head)->l_first = NULL; \
#define LIST_INSERT_HEAD(head, element, field) \ } while (0)
do { \
(element)->field.l_next = (head)->l_first; \ #define LIST_INSERT_HEAD(head, element, field) \
if ((head)->l_first != NULL) \ do { \
(head)->l_first->field.l_prev = &(element)->field.l_next; \ (element)->field.l_next = (head)->l_first; \
(head)->l_first = (element); \ if ((head)->l_first != NULL) \
(element)->field.l_prev = &(head)->l_first; \ (head)->l_first->field.l_prev = &(element)->field.l_next; \
} while (0) (head)->l_first = (element); \
#define LIST_REMOVE(element, field) \ (element)->field.l_prev = &(head)->l_first; \
do { \ } while (0)
if ((element)->field.l_next != NULL) \
(element)->field.l_next->field.l_prev = (element)->field.l_prev; \ #define LIST_REMOVE(element, field) \
*(element)->field.l_prev = (element)->field.l_next; \ do { \
} while (0) if ((element)->field.l_next != NULL) \
(element)->field.l_next->field.l_prev = (element)->field.l_prev; \
*(element)->field.l_prev = (element)->field.l_next; \
} while (0)
// TAILQ: Double-linked list with tail pointer. // TAILQ: Double-linked list with tail pointer.
#define TAILQ_HEAD(name, type) \ #define TAILQ_HEAD(name, type) \
struct name { \ struct name { \
struct type *t_first; \ struct type *t_first; \
struct type **t_last; \ struct type **t_last; \
} }
#define TAILQ_ENTRY(type) \ #define TAILQ_ENTRY(type) \
struct { \ struct { \
struct type *t_next; \ struct type *t_next; \
struct type **t_prev; \ struct type **t_prev; \
} }
#define TAILQ_EMPTY(head) ((head)->t_first == NULL) #define TAILQ_EMPTY(head) ((head)->t_first == NULL)
#define TAILQ_FIRST(head) ((head)->t_first) #define TAILQ_FIRST(head) ((head)->t_first)
#define TAILQ_FOREACH(var, head, field) \ #define TAILQ_FOREACH(var, head, field) \
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next) for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
#define TAILQ_INIT(head) \ #define TAILQ_INIT(head) \
do { \ do { \
(head)->t_first = NULL; \ (head)->t_first = NULL; \
(head)->t_last = &(head)->t_first; \ (head)->t_last = &(head)->t_first; \
} while (0) } while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) \ #define TAILQ_INSERT_TAIL(head, elm, field) \
do { \ do { \
(elm)->field.t_next = NULL; \ (elm)->field.t_next = NULL; \
(elm)->field.t_prev = (head)->t_last; \ (elm)->field.t_prev = (head)->t_last; \
*(head)->t_last = (elm); \ *(head)->t_last = (elm); \
(head)->t_last = &(elm)->field.t_next; \ (head)->t_last = &(elm)->field.t_next; \
} while (0) } while (0)
#define TAILQ_REMOVE(head, element, field) \ #define TAILQ_REMOVE(head, element, field) \
do { \ do { \
if ((element)->field.t_next != NULL) \ if ((element)->field.t_next != NULL) \
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \ (element)->field.t_next->field.t_prev = (element)->field.t_prev; \
else \ else \
(head)->t_last = (element)->field.t_prev; \ (head)->t_last = (element)->field.t_prev; \
*(element)->field.t_prev = (element)->field.t_next; \ *(element)->field.t_prev = (element)->field.t_next; \
} while (0) } while (0)
#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
@ -15,8 +17,10 @@
#if CONFIG_HAS_ARC4RANDOM_BUF #if CONFIG_HAS_ARC4RANDOM_BUF
void random_buf(void *buf, size_t len) { void
arc4random_buf(buf, len); random_buf(void *buf, size_t len)
{
arc4random_buf(buf, len);
} }
#elif CONFIG_HAS_GETRANDOM #elif CONFIG_HAS_GETRANDOM
@ -25,42 +29,48 @@ 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
for (;;) { random_buf(void *buf, size_t len)
ssize_t x = getrandom(buf, len, 0); {
if (x < 0) { for (;;) {
if (errno == EINTR) ssize_t x = getrandom(buf, len, 0);
continue; if (x < 0) {
os_printf("getrandom failed: %s", strerror(errno)); if (errno == EINTR)
abort(); continue;
} os_printf("getrandom failed: %s", strerror(errno));
if ((size_t)x == len) abort();
return; }
buf = (void *)((unsigned char *)buf + x); if ((size_t)x == len)
len -= (size_t)x; return;
} buf = (void *)((unsigned char *)buf + x);
len -= (size_t)x;
}
} }
#else #else
static int urandom; static int urandom;
static void open_urandom(void) { static void
urandom = open("/dev/urandom", O_RDONLY); open_urandom(void)
if (urandom < 0) { {
os_printf("Failed to open /dev/urandom\n"); urandom = open("/dev/urandom", O_RDONLY);
abort(); if (urandom < 0) {
} os_printf("Failed to open /dev/urandom\n");
abort();
}
} }
void random_buf(void *buf, size_t len) { void
static pthread_once_t open_once = PTHREAD_ONCE_INIT; random_buf(void *buf, size_t len)
pthread_once(&open_once, open_urandom); {
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
pthread_once(&open_once, open_urandom);
if ((size_t)read(urandom, buf, len) != len) { if ((size_t)read(urandom, buf, len) != len) {
os_printf("Short read on /dev/urandom\n"); os_printf("Short read on /dev/urandom\n");
abort(); abort();
} }
} }
#endif #endif
@ -72,15 +82,17 @@ 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
// Compute 2^k % upper random_uniform(uintmax_t upper)
// == (2^k - upper) % upper {
// == -upper % upper. // Compute 2^k % upper
uintmax_t lower = -upper % upper; // == (2^k - upper) % upper
for (;;) { // == -upper % upper.
uintmax_t value; uintmax_t lower = -upper % upper;
random_buf(&value, sizeof(value)); for (;;) {
if (value >= lower) uintmax_t value;
return value % upper; random_buf(&value, sizeof(value));
} if (value >= lower)
return value % 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);
@ -40,5 +43,5 @@ str_nullterminate(const char *s, size_t len) {
errno = EILSEQ; errno = EILSEQ;
return NULL; return NULL;
} }
return ret; return ret;
} }

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");
@ -167,13 +165,13 @@ wasm_cluster_create(WASMExecEnv *exec_env)
total_size = cluster_max_thread_num * sizeof(uint32); total_size = cluster_max_thread_num * sizeof(uint32);
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
|| !(cluster->stack_tops = || !(cluster->stack_tops =
wasm_runtime_malloc((uint32)total_size))) { wasm_runtime_malloc((uint32)total_size))) {
goto fail; goto fail;
} }
memset(cluster->stack_tops, 0, (uint32)total_size); memset(cluster->stack_tops, 0, (uint32)total_size);
if (!(cluster->stack_segment_occupied = if (!(cluster->stack_segment_occupied =
wasm_runtime_malloc(cluster_max_thread_num * sizeof(bool)))) { wasm_runtime_malloc(cluster_max_thread_num * sizeof(bool)))) {
goto fail; goto fail;
} }
memset(cluster->stack_segment_occupied, 0, memset(cluster->stack_segment_occupied, 0,
@ -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);
@ -302,7 +300,7 @@ wasm_cluster_search_exec_env(WASMCluster *cluster,
} }
/* search the global cluster list to find if the given /* search the global cluster list to find if the given
module instance have a corresponding exec_env */ module instance have a corresponding exec_env */
WASMExecEnv * WASMExecEnv *
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst) wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst)
{ {
@ -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,9 +461,10 @@ 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
(void *)new_exec_env, != os_thread_create(&tid, thread_manager_start_routine,
APP_THREAD_STACK_SIZE_DEFAULT)) { (void *)new_exec_env,
APP_THREAD_STACK_SIZE_DEFAULT)) {
goto fail3; goto fail3;
} }
@ -520,9 +516,10 @@ 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 {
|| exec_env->current_status->running_status == STATUS_STEP; return exec_env->current_status->running_status == STATUS_RUNNING
|| exec_env->current_status->running_status == STATUS_STEP;
} }
void void
@ -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);
@ -654,12 +653,12 @@ wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
{ {
/* Set the termination flag */ /* Set the termination flag */
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
wasm_cluster_thread_exited(exec_env); wasm_cluster_thread_exited(exec_env);
#else #else
exec_env->suspend_flags.flags |= 0x01; exec_env->suspend_flags.flags |= 0x01;
#endif #endif
return 0; return 0;
} }
static void static void
@ -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

@ -16,30 +16,28 @@
extern "C" { extern "C" {
#endif #endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
#define WAMR_SIG_TRAP (5) #define WAMR_SIG_TRAP (5)
#define WAMR_SIG_STOP (19) #define WAMR_SIG_STOP (19)
#define WAMR_SIG_TERM (15) #define WAMR_SIG_TERM (15)
#define WAMR_SIG_SINGSTEP (0x1ff) #define WAMR_SIG_SINGSTEP (0x1ff)
#define STATUS_RUNNING (0) #define STATUS_RUNNING (0)
#define STATUS_STOP (1) #define STATUS_STOP (1)
#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);