mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
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:
parent
dc65d2910a
commit
fb4afc7ca4
|
@ -399,6 +399,7 @@ jobs:
|
|||
cmake --build . --config Release --parallel 4
|
||||
./callback
|
||||
./callback_chain
|
||||
./empty_imports
|
||||
./global
|
||||
./hello
|
||||
./hostref
|
||||
|
|
2
.github/workflows/spec_test.yml
vendored
2
.github/workflows/spec_test.yml
vendored
|
@ -6,6 +6,7 @@ on:
|
|||
# will be triggered on PR events
|
||||
pull_request:
|
||||
paths:
|
||||
- "core/config.h"
|
||||
- "core/iwasm/**"
|
||||
- "core/shared/**"
|
||||
- "wamr-compiler/**"
|
||||
|
@ -13,6 +14,7 @@ on:
|
|||
# will be triggered on push events
|
||||
push:
|
||||
paths:
|
||||
- "core/config.h"
|
||||
- "core/iwasm/**"
|
||||
- "core/shared/**"
|
||||
- "wamr-compiler/**"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
/* clang-format off */
|
||||
#if !defined(BUILD_TARGET_X86_64) \
|
||||
&& !defined(BUILD_TARGET_AMD_64) \
|
||||
&& !defined(BUILD_TARGET_AARCH64) \
|
||||
|
@ -21,6 +22,7 @@
|
|||
&& !defined(BUILD_TARGET_RISCV32_ILP32D) \
|
||||
&& !defined(BUILD_TARGET_RISCV32_ILP32) \
|
||||
&& !defined(BUILD_TARGET_ARC)
|
||||
/* clang-format on */
|
||||
#if defined(__x86_64__) || defined(__x86_64)
|
||||
#define BUILD_TARGET_X86_64
|
||||
#elif defined(__amd64__) || defined(__amd64)
|
||||
|
@ -54,7 +56,7 @@
|
|||
#define BH_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define MEM_ALLOCATOR_EMS 0
|
||||
#define MEM_ALLOCATOR_EMS 0
|
||||
#define MEM_ALLOCATOR_TLSF 1
|
||||
|
||||
/* Default memory allocator */
|
||||
|
@ -268,8 +270,8 @@
|
|||
#define APP_THREAD_STACK_SIZE_DEFAULT (6 * 1024)
|
||||
#define APP_THREAD_STACK_SIZE_MIN (4 * 1024)
|
||||
#elif defined(PTHREAD_STACK_DEFAULT) && defined(PTHREAD_STACK_MIN)
|
||||
#define APP_THREAD_STACK_SIZE_DEFAULT PTHREAD_STACK_DEFAULT
|
||||
#define APP_THREAD_STACK_SIZE_MIN PTHREAD_STACK_MIN
|
||||
#define APP_THREAD_STACK_SIZE_DEFAULT PTHREAD_STACK_DEFAULT
|
||||
#define APP_THREAD_STACK_SIZE_MIN PTHREAD_STACK_MIN
|
||||
#else
|
||||
#define APP_THREAD_STACK_SIZE_DEFAULT (32 * 1024)
|
||||
#define APP_THREAD_STACK_SIZE_MIN (24 * 1024)
|
||||
|
@ -312,4 +314,3 @@
|
|||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
#include "aot.h"
|
||||
|
||||
|
||||
static char aot_error[128];
|
||||
|
||||
char*
|
||||
char *
|
||||
aot_get_last_error()
|
||||
{
|
||||
return aot_error[0] == '\0' ? "" : aot_error;
|
||||
return aot_error[0] == '\0' ? "" : aot_error;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -26,558 +25,561 @@ aot_set_last_error_v(const char *format, ...)
|
|||
void
|
||||
aot_set_last_error(const char *error)
|
||||
{
|
||||
if (error)
|
||||
snprintf(aot_error, sizeof(aot_error), "Error: %s", error);
|
||||
else
|
||||
aot_error[0] = '\0';
|
||||
if (error)
|
||||
snprintf(aot_error, sizeof(aot_error), "Error: %s", error);
|
||||
else
|
||||
aot_error[0] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
aot_destroy_mem_init_data_list(AOTMemInitData **data_list, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (data_list[i])
|
||||
wasm_runtime_free(data_list[i]);
|
||||
wasm_runtime_free(data_list);
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (data_list[i])
|
||||
wasm_runtime_free(data_list[i]);
|
||||
wasm_runtime_free(data_list);
|
||||
}
|
||||
|
||||
static AOTMemInitData **
|
||||
aot_create_mem_init_data_list(const WASMModule *module)
|
||||
{
|
||||
AOTMemInitData **data_list;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
AOTMemInitData **data_list;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
|
||||
/* Allocate memory */
|
||||
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;
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTMemInitData *) * (uint64)module->data_seg_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
goto fail;
|
||||
|| !(data_list = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
memset(data_list, 0, size);
|
||||
|
||||
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:
|
||||
aot_destroy_mem_init_data_list(data_list, module->data_seg_count);
|
||||
return NULL;
|
||||
aot_destroy_mem_init_data_list(data_list, module->data_seg_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
aot_destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (data_list[i])
|
||||
wasm_runtime_free(data_list[i]);
|
||||
wasm_runtime_free(data_list);
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (data_list[i])
|
||||
wasm_runtime_free(data_list[i]);
|
||||
wasm_runtime_free(data_list);
|
||||
}
|
||||
|
||||
static AOTTableInitData **
|
||||
aot_create_table_init_data_list(const WASMModule *module)
|
||||
{
|
||||
AOTTableInitData **data_list;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
AOTTableInitData **data_list;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
|
||||
/* Allocate memory */
|
||||
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;
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTTableInitData *) * (uint64)module->table_seg_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
goto fail;
|
||||
|| !(data_list = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
memset(data_list, 0, size);
|
||||
|
||||
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:
|
||||
aot_destroy_table_init_data_list(data_list, module->table_seg_count);
|
||||
return NULL;
|
||||
aot_destroy_table_init_data_list(data_list, module->table_seg_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static AOTImportGlobal *
|
||||
aot_create_import_globals(const WASMModule *module,
|
||||
uint32 *p_import_global_data_size)
|
||||
{
|
||||
AOTImportGlobal *import_globals;
|
||||
uint64 size;
|
||||
uint32 i, data_offset = 0;
|
||||
AOTImportGlobal *import_globals;
|
||||
uint64 size;
|
||||
uint32 i, data_offset = 0;
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(import_globals = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(import_globals = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(import_globals, 0, (uint32)size);
|
||||
memset(import_globals, 0, (uint32)size);
|
||||
|
||||
/* Create each import global */
|
||||
for (i = 0; i < module->import_global_count; i++) {
|
||||
WASMGlobalImport *import_global = &module->import_globals[i].u.global;
|
||||
import_globals[i].module_name = import_global->module_name;
|
||||
import_globals[i].global_name = import_global->field_name;
|
||||
import_globals[i].type = import_global->type;
|
||||
import_globals[i].is_mutable = import_global->is_mutable;
|
||||
import_globals[i].global_data_linked = import_global->global_data_linked;
|
||||
import_globals[i].size = wasm_value_type_size(import_global->type);
|
||||
/* Calculate data offset */
|
||||
import_globals[i].data_offset = data_offset;
|
||||
data_offset += wasm_value_type_size(import_global->type);
|
||||
}
|
||||
/* Create each import global */
|
||||
for (i = 0; i < module->import_global_count; i++) {
|
||||
WASMGlobalImport *import_global = &module->import_globals[i].u.global;
|
||||
import_globals[i].module_name = import_global->module_name;
|
||||
import_globals[i].global_name = import_global->field_name;
|
||||
import_globals[i].type = import_global->type;
|
||||
import_globals[i].is_mutable = import_global->is_mutable;
|
||||
import_globals[i].global_data_linked =
|
||||
import_global->global_data_linked;
|
||||
import_globals[i].size = wasm_value_type_size(import_global->type);
|
||||
/* Calculate data offset */
|
||||
import_globals[i].data_offset = data_offset;
|
||||
data_offset += wasm_value_type_size(import_global->type);
|
||||
}
|
||||
|
||||
*p_import_global_data_size = data_offset;
|
||||
return import_globals;
|
||||
*p_import_global_data_size = data_offset;
|
||||
return import_globals;
|
||||
}
|
||||
|
||||
static AOTGlobal *
|
||||
aot_create_globals(const WASMModule *module,
|
||||
uint32 global_data_start_offset,
|
||||
aot_create_globals(const WASMModule *module, uint32 global_data_start_offset,
|
||||
uint32 *p_global_data_size)
|
||||
{
|
||||
AOTGlobal *globals;
|
||||
uint64 size;
|
||||
uint32 i, data_offset = global_data_start_offset;
|
||||
AOTGlobal *globals;
|
||||
uint64 size;
|
||||
uint32 i, data_offset = global_data_start_offset;
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTGlobal) * (uint64)module->global_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(globals = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTGlobal) * (uint64)module->global_count;
|
||||
if (size >= UINT32_MAX || !(globals = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(globals, 0, (uint32)size);
|
||||
memset(globals, 0, (uint32)size);
|
||||
|
||||
/* Create each global */
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
WASMGlobal *global = &module->globals[i];
|
||||
globals[i].type = global->type;
|
||||
globals[i].is_mutable = global->is_mutable;
|
||||
globals[i].size = wasm_value_type_size(global->type);
|
||||
memcpy(&globals[i].init_expr, &global->init_expr,
|
||||
sizeof(global->init_expr));
|
||||
/* Calculate data offset */
|
||||
globals[i].data_offset = data_offset;
|
||||
data_offset += wasm_value_type_size(global->type);
|
||||
}
|
||||
/* Create each global */
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
WASMGlobal *global = &module->globals[i];
|
||||
globals[i].type = global->type;
|
||||
globals[i].is_mutable = global->is_mutable;
|
||||
globals[i].size = wasm_value_type_size(global->type);
|
||||
memcpy(&globals[i].init_expr, &global->init_expr,
|
||||
sizeof(global->init_expr));
|
||||
/* Calculate data offset */
|
||||
globals[i].data_offset = data_offset;
|
||||
data_offset += wasm_value_type_size(global->type);
|
||||
}
|
||||
|
||||
*p_global_data_size = data_offset - global_data_start_offset;
|
||||
return globals;
|
||||
*p_global_data_size = data_offset - global_data_start_offset;
|
||||
return globals;
|
||||
}
|
||||
|
||||
static void
|
||||
aot_destroy_func_types(AOTFuncType **func_types, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (func_types[i])
|
||||
wasm_runtime_free(func_types[i]);
|
||||
wasm_runtime_free(func_types);
|
||||
uint32 i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (func_types[i])
|
||||
wasm_runtime_free(func_types[i]);
|
||||
wasm_runtime_free(func_types);
|
||||
}
|
||||
|
||||
static AOTFuncType **
|
||||
aot_create_func_types(const WASMModule *module)
|
||||
{
|
||||
AOTFuncType **func_types;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
AOTFuncType **func_types;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
|
||||
/* Allocate memory */
|
||||
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;
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTFuncType *) * (uint64)module->type_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(func_types[i] = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
goto fail;
|
||||
|| !(func_types = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
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:
|
||||
aot_destroy_func_types(func_types, module->type_count);
|
||||
return NULL;
|
||||
aot_destroy_func_types(func_types, module->type_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static AOTImportFunc *
|
||||
aot_create_import_funcs(const WASMModule *module)
|
||||
{
|
||||
AOTImportFunc *import_funcs;
|
||||
uint64 size;
|
||||
uint32 i, j;
|
||||
AOTImportFunc *import_funcs;
|
||||
uint64 size;
|
||||
uint32 i, j;
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportFunc) * (uint64)module->import_function_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(import_funcs = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportFunc) * (uint64)module->import_function_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(import_funcs = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create each import function */
|
||||
for (i = 0; i < module->import_function_count; i++) {
|
||||
WASMFunctionImport *import_func = &module->import_functions[i].u.function;
|
||||
import_funcs[i].module_name = import_func->module_name;
|
||||
import_funcs[i].func_name = import_func->field_name;
|
||||
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
|
||||
import_funcs[i].func_type = import_func->func_type;
|
||||
import_funcs[i].signature = import_func->signature;
|
||||
import_funcs[i].attachment = import_func->attachment;
|
||||
import_funcs[i].call_conv_raw = import_func->call_conv_raw;
|
||||
import_funcs[i].call_conv_wasm_c_api = false;
|
||||
/* Resolve function type index */
|
||||
for (j = 0; j < module->type_count; j++)
|
||||
if (import_func->func_type == module->types[j]) {
|
||||
import_funcs[i].func_type_index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Create each import function */
|
||||
for (i = 0; i < module->import_function_count; i++) {
|
||||
WASMFunctionImport *import_func =
|
||||
&module->import_functions[i].u.function;
|
||||
import_funcs[i].module_name = import_func->module_name;
|
||||
import_funcs[i].func_name = import_func->field_name;
|
||||
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
|
||||
import_funcs[i].func_type = import_func->func_type;
|
||||
import_funcs[i].signature = import_func->signature;
|
||||
import_funcs[i].attachment = import_func->attachment;
|
||||
import_funcs[i].call_conv_raw = import_func->call_conv_raw;
|
||||
import_funcs[i].call_conv_wasm_c_api = false;
|
||||
/* Resolve function type index */
|
||||
for (j = 0; j < module->type_count; j++)
|
||||
if (import_func->func_type == module->types[j]) {
|
||||
import_funcs[i].func_type_index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return import_funcs;
|
||||
return import_funcs;
|
||||
}
|
||||
|
||||
static void
|
||||
aot_destroy_funcs(AOTFunc **funcs, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (funcs[i])
|
||||
wasm_runtime_free(funcs[i]);
|
||||
wasm_runtime_free(funcs);
|
||||
for (i = 0; i < count; i++)
|
||||
if (funcs[i])
|
||||
wasm_runtime_free(funcs[i]);
|
||||
wasm_runtime_free(funcs);
|
||||
}
|
||||
|
||||
static AOTFunc **
|
||||
aot_create_funcs(const WASMModule *module)
|
||||
{
|
||||
AOTFunc **funcs;
|
||||
uint64 size;
|
||||
uint32 i, j;
|
||||
AOTFunc **funcs;
|
||||
uint64 size;
|
||||
uint32 i, j;
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTFunc*) * (uint64)module->function_count;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(funcs = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
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;
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTFunc *) * (uint64)module->function_count;
|
||||
if (size >= UINT32_MAX || !(funcs = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
funcs[i]->func_type = func->func_type;
|
||||
memset(funcs, 0, size);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
funcs[i]->func_type = func->func_type;
|
||||
|
||||
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:
|
||||
aot_destroy_funcs(funcs, module->function_count);
|
||||
return NULL;
|
||||
aot_destroy_funcs(funcs, module->function_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AOTCompData*
|
||||
AOTCompData *
|
||||
aot_create_comp_data(WASMModule *module)
|
||||
{
|
||||
AOTCompData *comp_data;
|
||||
uint32 import_global_data_size = 0, global_data_size = 0, i, j;
|
||||
uint64 size;
|
||||
AOTCompData *comp_data;
|
||||
uint32 import_global_data_size = 0, global_data_size = 0, i, j;
|
||||
uint64 size;
|
||||
|
||||
/* Allocate memory */
|
||||
if (!(comp_data = wasm_runtime_malloc(sizeof(AOTCompData)))) {
|
||||
aot_set_last_error("create compile data failed.\n");
|
||||
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;
|
||||
/* Allocate memory */
|
||||
if (!(comp_data = wasm_runtime_malloc(sizeof(AOTCompData)))) {
|
||||
aot_set_last_error("create compile data failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
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 */
|
||||
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;
|
||||
memset(comp_data, 0, sizeof(AOTCompData));
|
||||
|
||||
/* Create tables */
|
||||
comp_data->table_count = module->import_table_count + module->table_count;
|
||||
comp_data->memory_count =
|
||||
module->import_memory_count + module->memory_count;
|
||||
|
||||
if (comp_data->table_count > 0) {
|
||||
size = sizeof(AOTTable) * (uint64)comp_data->table_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->tables = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("create memories array failed.\n");
|
||||
goto fail;
|
||||
|| !(comp_data->memories = 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create table data segments */
|
||||
comp_data->table_init_data_count = module->table_seg_count;
|
||||
if (comp_data->table_init_data_count > 0
|
||||
&& !(comp_data->table_init_data_list =
|
||||
aot_create_table_init_data_list(module)))
|
||||
goto fail;
|
||||
/* 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 import globals */
|
||||
comp_data->import_global_count = module->import_global_count;
|
||||
if (comp_data->import_global_count > 0
|
||||
&& !(comp_data->import_globals =
|
||||
aot_create_import_globals(module, &import_global_data_size)))
|
||||
goto fail;
|
||||
/* Create memory data segments */
|
||||
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 globals */
|
||||
comp_data->global_count = module->global_count;
|
||||
if (comp_data->global_count
|
||||
&& !(comp_data->globals = aot_create_globals
|
||||
(module, import_global_data_size, &global_data_size)))
|
||||
goto fail;
|
||||
/* Create tables */
|
||||
comp_data->table_count = module->import_table_count + module->table_count;
|
||||
|
||||
comp_data->global_data_size = import_global_data_size +
|
||||
global_data_size;
|
||||
if (comp_data->table_count > 0) {
|
||||
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 */
|
||||
comp_data->func_type_count = module->type_count;
|
||||
if (comp_data->func_type_count
|
||||
&& !(comp_data->func_types = aot_create_func_types(module)))
|
||||
goto fail;
|
||||
/* Create table data segments */
|
||||
comp_data->table_init_data_count = module->table_seg_count;
|
||||
if (comp_data->table_init_data_count > 0
|
||||
&& !(comp_data->table_init_data_list =
|
||||
aot_create_table_init_data_list(module)))
|
||||
goto fail;
|
||||
|
||||
/* 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;
|
||||
/* Create import globals */
|
||||
comp_data->import_global_count = module->import_global_count;
|
||||
if (comp_data->import_global_count > 0
|
||||
&& !(comp_data->import_globals =
|
||||
aot_create_import_globals(module, &import_global_data_size)))
|
||||
goto fail;
|
||||
|
||||
/* Create functions */
|
||||
comp_data->func_count = module->function_count;
|
||||
if (comp_data->func_count
|
||||
&& !(comp_data->funcs = aot_create_funcs(module)))
|
||||
goto fail;
|
||||
/* Create globals */
|
||||
comp_data->global_count = module->global_count;
|
||||
if (comp_data->global_count
|
||||
&& !(comp_data->globals = aot_create_globals(
|
||||
module, import_global_data_size, &global_data_size)))
|
||||
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->global_data_size = import_global_data_size + global_data_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;
|
||||
/* Create function types */
|
||||
comp_data->func_type_count = module->type_count;
|
||||
if (comp_data->func_type_count
|
||||
&& !(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:
|
||||
|
||||
aot_destroy_comp_data(comp_data);
|
||||
return NULL;
|
||||
aot_destroy_comp_data(comp_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aot_destroy_comp_data(AOTCompData *comp_data)
|
||||
{
|
||||
if (!comp_data)
|
||||
return;
|
||||
if (!comp_data)
|
||||
return;
|
||||
|
||||
if (comp_data->import_memories)
|
||||
wasm_runtime_free(comp_data->import_memories);
|
||||
if (comp_data->import_memories)
|
||||
wasm_runtime_free(comp_data->import_memories);
|
||||
|
||||
if (comp_data->memories)
|
||||
wasm_runtime_free(comp_data->memories);
|
||||
if (comp_data->memories)
|
||||
wasm_runtime_free(comp_data->memories);
|
||||
|
||||
if (comp_data->mem_init_data_list)
|
||||
aot_destroy_mem_init_data_list(comp_data->mem_init_data_list,
|
||||
comp_data->mem_init_data_count);
|
||||
if (comp_data->mem_init_data_list)
|
||||
aot_destroy_mem_init_data_list(comp_data->mem_init_data_list,
|
||||
comp_data->mem_init_data_count);
|
||||
|
||||
if (comp_data->import_tables)
|
||||
wasm_runtime_free(comp_data->import_tables);
|
||||
if (comp_data->import_tables)
|
||||
wasm_runtime_free(comp_data->import_tables);
|
||||
|
||||
if (comp_data->tables)
|
||||
wasm_runtime_free(comp_data->tables);
|
||||
if (comp_data->tables)
|
||||
wasm_runtime_free(comp_data->tables);
|
||||
|
||||
if (comp_data->table_init_data_list)
|
||||
aot_destroy_table_init_data_list(comp_data->table_init_data_list,
|
||||
comp_data->table_init_data_count);
|
||||
if (comp_data->table_init_data_list)
|
||||
aot_destroy_table_init_data_list(comp_data->table_init_data_list,
|
||||
comp_data->table_init_data_count);
|
||||
|
||||
if (comp_data->import_globals)
|
||||
wasm_runtime_free(comp_data->import_globals);
|
||||
if (comp_data->import_globals)
|
||||
wasm_runtime_free(comp_data->import_globals);
|
||||
|
||||
if (comp_data->globals)
|
||||
wasm_runtime_free(comp_data->globals);
|
||||
if (comp_data->globals)
|
||||
wasm_runtime_free(comp_data->globals);
|
||||
|
||||
if (comp_data->func_types)
|
||||
aot_destroy_func_types(comp_data->func_types,
|
||||
comp_data->func_type_count);
|
||||
if (comp_data->func_types)
|
||||
aot_destroy_func_types(comp_data->func_types,
|
||||
comp_data->func_type_count);
|
||||
|
||||
if (comp_data->import_funcs)
|
||||
wasm_runtime_free(comp_data->import_funcs);
|
||||
if (comp_data->import_funcs)
|
||||
wasm_runtime_free(comp_data->import_funcs);
|
||||
|
||||
if (comp_data->funcs)
|
||||
aot_destroy_funcs(comp_data->funcs, comp_data->func_count);
|
||||
if (comp_data->funcs)
|
||||
aot_destroy_funcs(comp_data->funcs, comp_data->func_count);
|
||||
|
||||
wasm_runtime_free(comp_data);
|
||||
wasm_runtime_free(comp_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,54 +22,54 @@ typedef WASMType AOTFuncType;
|
|||
typedef WASMExport AOTExport;
|
||||
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
typedef void * dwar_extractor_handle_t;
|
||||
typedef void *dwar_extractor_handle_t;
|
||||
#endif
|
||||
|
||||
typedef enum AOTIntCond {
|
||||
INT_EQZ = 0,
|
||||
INT_EQ,
|
||||
INT_NE,
|
||||
INT_LT_S,
|
||||
INT_LT_U,
|
||||
INT_GT_S,
|
||||
INT_GT_U,
|
||||
INT_LE_S,
|
||||
INT_LE_U,
|
||||
INT_GE_S,
|
||||
INT_GE_U
|
||||
INT_EQZ = 0,
|
||||
INT_EQ,
|
||||
INT_NE,
|
||||
INT_LT_S,
|
||||
INT_LT_U,
|
||||
INT_GT_S,
|
||||
INT_GT_U,
|
||||
INT_LE_S,
|
||||
INT_LE_U,
|
||||
INT_GE_S,
|
||||
INT_GE_U
|
||||
} AOTIntCond;
|
||||
|
||||
typedef enum AOTFloatCond {
|
||||
FLOAT_EQ = 0,
|
||||
FLOAT_NE,
|
||||
FLOAT_LT,
|
||||
FLOAT_GT,
|
||||
FLOAT_LE,
|
||||
FLOAT_GE,
|
||||
FLOAT_UNO
|
||||
FLOAT_EQ = 0,
|
||||
FLOAT_NE,
|
||||
FLOAT_LT,
|
||||
FLOAT_GT,
|
||||
FLOAT_LE,
|
||||
FLOAT_GE,
|
||||
FLOAT_UNO
|
||||
} AOTFloatCond;
|
||||
|
||||
/**
|
||||
* Import memory
|
||||
*/
|
||||
typedef struct AOTImportMemory {
|
||||
char *module_name;
|
||||
char *memory_name;
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
char *module_name;
|
||||
char *memory_name;
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
} AOTImportMemory;
|
||||
|
||||
/**
|
||||
* Memory information
|
||||
*/
|
||||
typedef struct AOTMemory {
|
||||
/* memory info */
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
/* memory info */
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
} AOTMemory;
|
||||
|
||||
/**
|
||||
|
@ -77,202 +77,202 @@ typedef struct AOTMemory {
|
|||
*/
|
||||
typedef struct AOTMemInitData {
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
/* Passive flag */
|
||||
bool is_passive;
|
||||
/* memory index */
|
||||
uint32 memory_index;
|
||||
/* Passive flag */
|
||||
bool is_passive;
|
||||
/* memory index */
|
||||
uint32 memory_index;
|
||||
#endif
|
||||
/* Start address of init data */
|
||||
AOTInitExpr offset;
|
||||
/* Byte count */
|
||||
uint32 byte_count;
|
||||
/* Byte array */
|
||||
uint8 bytes[1];
|
||||
/* Start address of init data */
|
||||
AOTInitExpr offset;
|
||||
/* Byte count */
|
||||
uint32 byte_count;
|
||||
/* Byte array */
|
||||
uint8 bytes[1];
|
||||
} AOTMemInitData;
|
||||
|
||||
/**
|
||||
* Import table
|
||||
*/
|
||||
typedef struct AOTImportTable {
|
||||
char *module_name;
|
||||
char *table_name;
|
||||
uint32 table_flags;
|
||||
uint32 table_init_size;
|
||||
uint32 table_max_size;
|
||||
bool possible_grow;
|
||||
char *module_name;
|
||||
char *table_name;
|
||||
uint32 table_flags;
|
||||
uint32 table_init_size;
|
||||
uint32 table_max_size;
|
||||
bool possible_grow;
|
||||
} AOTImportTable;
|
||||
|
||||
/**
|
||||
* Table
|
||||
*/
|
||||
typedef struct AOTTable {
|
||||
uint32 elem_type;
|
||||
uint32 table_flags;
|
||||
uint32 table_init_size;
|
||||
uint32 table_max_size;
|
||||
bool possible_grow;
|
||||
uint32 elem_type;
|
||||
uint32 table_flags;
|
||||
uint32 table_init_size;
|
||||
uint32 table_max_size;
|
||||
bool possible_grow;
|
||||
} AOTTable;
|
||||
|
||||
/**
|
||||
* A segment of table init data
|
||||
*/
|
||||
typedef struct AOTTableInitData {
|
||||
/* 0 to 7 */
|
||||
uint32 mode;
|
||||
/* funcref or externref, elemkind will be considered as funcref */
|
||||
uint32 elem_type;
|
||||
bool is_dropped;
|
||||
/* optional, only for active */
|
||||
uint32 table_index;
|
||||
/* Start address of init data */
|
||||
AOTInitExpr offset;
|
||||
/* Function index count */
|
||||
uint32 func_index_count;
|
||||
/* Function index array */
|
||||
uint32 func_indexes[1];
|
||||
/* 0 to 7 */
|
||||
uint32 mode;
|
||||
/* funcref or externref, elemkind will be considered as funcref */
|
||||
uint32 elem_type;
|
||||
bool is_dropped;
|
||||
/* optional, only for active */
|
||||
uint32 table_index;
|
||||
/* Start address of init data */
|
||||
AOTInitExpr offset;
|
||||
/* Function index count */
|
||||
uint32 func_index_count;
|
||||
/* Function index array */
|
||||
uint32 func_indexes[1];
|
||||
} AOTTableInitData;
|
||||
|
||||
/**
|
||||
* Import global variable
|
||||
*/
|
||||
typedef struct AOTImportGlobal {
|
||||
char *module_name;
|
||||
char *global_name;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
/* global data after linked */
|
||||
WASMValue global_data_linked;
|
||||
char *module_name;
|
||||
char *global_name;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
/* global data after linked */
|
||||
WASMValue global_data_linked;
|
||||
} AOTImportGlobal;
|
||||
|
||||
/**
|
||||
* Global variable
|
||||
*/
|
||||
typedef struct AOTGlobal {
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
AOTInitExpr init_expr;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
uint32 size;
|
||||
/* The data offset of current global in global data */
|
||||
uint32 data_offset;
|
||||
AOTInitExpr init_expr;
|
||||
} AOTGlobal;
|
||||
|
||||
/**
|
||||
* Import function
|
||||
*/
|
||||
typedef struct AOTImportFunc {
|
||||
char *module_name;
|
||||
char *func_name;
|
||||
AOTFuncType *func_type;
|
||||
uint32 func_type_index;
|
||||
/* function pointer after linked */
|
||||
void *func_ptr_linked;
|
||||
/* signature from registered native symbols */
|
||||
const char *signature;
|
||||
/* attachment */
|
||||
void *attachment;
|
||||
bool call_conv_raw;
|
||||
bool call_conv_wasm_c_api;
|
||||
bool wasm_c_api_with_env;
|
||||
char *module_name;
|
||||
char *func_name;
|
||||
AOTFuncType *func_type;
|
||||
uint32 func_type_index;
|
||||
/* function pointer after linked */
|
||||
void *func_ptr_linked;
|
||||
/* signature from registered native symbols */
|
||||
const char *signature;
|
||||
/* attachment */
|
||||
void *attachment;
|
||||
bool call_conv_raw;
|
||||
bool call_conv_wasm_c_api;
|
||||
bool wasm_c_api_with_env;
|
||||
} AOTImportFunc;
|
||||
|
||||
/**
|
||||
* Function
|
||||
*/
|
||||
typedef struct AOTFunc {
|
||||
AOTFuncType *func_type;
|
||||
uint32 func_type_index;
|
||||
uint32 local_count;
|
||||
uint8 *local_types;
|
||||
uint16 param_cell_num;
|
||||
uint16 local_cell_num;
|
||||
uint32 code_size;
|
||||
uint8 *code;
|
||||
AOTFuncType *func_type;
|
||||
uint32 func_type_index;
|
||||
uint32 local_count;
|
||||
uint8 *local_types;
|
||||
uint16 param_cell_num;
|
||||
uint16 local_cell_num;
|
||||
uint32 code_size;
|
||||
uint8 *code;
|
||||
} AOTFunc;
|
||||
|
||||
typedef struct AOTCompData {
|
||||
/* Import memories */
|
||||
uint32 import_memory_count;
|
||||
AOTImportMemory *import_memories;
|
||||
/* Import memories */
|
||||
uint32 import_memory_count;
|
||||
AOTImportMemory *import_memories;
|
||||
|
||||
/* Memories */
|
||||
uint32 memory_count;
|
||||
AOTMemory *memories;
|
||||
/* Memories */
|
||||
uint32 memory_count;
|
||||
AOTMemory *memories;
|
||||
|
||||
/* Memory init data info */
|
||||
uint32 mem_init_data_count;
|
||||
AOTMemInitData **mem_init_data_list;
|
||||
/* Memory init data info */
|
||||
uint32 mem_init_data_count;
|
||||
AOTMemInitData **mem_init_data_list;
|
||||
|
||||
/* Import tables */
|
||||
uint32 import_table_count;
|
||||
AOTImportTable *import_tables;
|
||||
/* Import tables */
|
||||
uint32 import_table_count;
|
||||
AOTImportTable *import_tables;
|
||||
|
||||
/* Tables */
|
||||
uint32 table_count;
|
||||
AOTTable *tables;
|
||||
/* Tables */
|
||||
uint32 table_count;
|
||||
AOTTable *tables;
|
||||
|
||||
/* Table init data info */
|
||||
uint32 table_init_data_count;
|
||||
AOTTableInitData **table_init_data_list;
|
||||
/* Table init data info */
|
||||
uint32 table_init_data_count;
|
||||
AOTTableInitData **table_init_data_list;
|
||||
|
||||
/* Import globals */
|
||||
uint32 import_global_count;
|
||||
AOTImportGlobal *import_globals;
|
||||
/* Import globals */
|
||||
uint32 import_global_count;
|
||||
AOTImportGlobal *import_globals;
|
||||
|
||||
/* Globals */
|
||||
uint32 global_count;
|
||||
AOTGlobal *globals;
|
||||
/* Globals */
|
||||
uint32 global_count;
|
||||
AOTGlobal *globals;
|
||||
|
||||
/* Function types */
|
||||
uint32 func_type_count;
|
||||
AOTFuncType **func_types;
|
||||
/* Function types */
|
||||
uint32 func_type_count;
|
||||
AOTFuncType **func_types;
|
||||
|
||||
/* Import functions */
|
||||
uint32 import_func_count;
|
||||
AOTImportFunc *import_funcs;
|
||||
/* Import functions */
|
||||
uint32 import_func_count;
|
||||
AOTImportFunc *import_funcs;
|
||||
|
||||
/* Functions */
|
||||
uint32 func_count;
|
||||
AOTFunc **funcs;
|
||||
/* Functions */
|
||||
uint32 func_count;
|
||||
AOTFunc **funcs;
|
||||
|
||||
uint32 global_data_size;
|
||||
uint32 global_data_size;
|
||||
|
||||
uint32 start_func_index;
|
||||
uint32 malloc_func_index;
|
||||
uint32 free_func_index;
|
||||
uint32 retain_func_index;
|
||||
uint32 start_func_index;
|
||||
uint32 malloc_func_index;
|
||||
uint32 free_func_index;
|
||||
uint32 retain_func_index;
|
||||
|
||||
uint32 aux_data_end_global_index;
|
||||
uint32 aux_data_end;
|
||||
uint32 aux_heap_base_global_index;
|
||||
uint32 aux_heap_base;
|
||||
uint32 aux_stack_top_global_index;
|
||||
uint32 aux_stack_bottom;
|
||||
uint32 aux_stack_size;
|
||||
uint32 aux_data_end_global_index;
|
||||
uint32 aux_data_end;
|
||||
uint32 aux_heap_base_global_index;
|
||||
uint32 aux_heap_base;
|
||||
uint32 aux_stack_top_global_index;
|
||||
uint32 aux_stack_bottom;
|
||||
uint32 aux_stack_size;
|
||||
|
||||
WASMModule *wasm_module;
|
||||
WASMModule *wasm_module;
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
dwar_extractor_handle_t extractor;
|
||||
dwar_extractor_handle_t extractor;
|
||||
#endif
|
||||
} AOTCompData;
|
||||
|
||||
typedef struct AOTNativeSymbol {
|
||||
bh_list_link link;
|
||||
const char *symbol;
|
||||
int32 index;
|
||||
bh_list_link link;
|
||||
const char *symbol;
|
||||
int32 index;
|
||||
} AOTNativeSymbol;
|
||||
|
||||
AOTCompData*
|
||||
AOTCompData *
|
||||
aot_create_comp_data(WASMModule *module);
|
||||
|
||||
void
|
||||
aot_destroy_comp_data(AOTCompData *comp_data);
|
||||
|
||||
char*
|
||||
char *
|
||||
aot_get_last_error();
|
||||
|
||||
void
|
||||
|
@ -282,14 +282,16 @@ void
|
|||
aot_set_last_error_v(const char *format, ...);
|
||||
|
||||
#if BH_DEBUG != 0
|
||||
#define HANDLE_FAILURE(callee) do { \
|
||||
aot_set_last_error_v("call %s failed in %s:%d", (callee),\
|
||||
__FUNCTION__, __LINE__); \
|
||||
} while (0)
|
||||
#define HANDLE_FAILURE(callee) \
|
||||
do { \
|
||||
aot_set_last_error_v("call %s failed in %s:%d", (callee), \
|
||||
__FUNCTION__, __LINE__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define HANDLE_FAILURE(callee) do { \
|
||||
aot_set_last_error_v("call %s failed", (callee)); \
|
||||
} while (0)
|
||||
#define HANDLE_FAILURE(callee) \
|
||||
do { \
|
||||
aot_set_last_error_v("call %s failed", (callee)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static inline uint32
|
||||
|
@ -309,4 +311,3 @@ aot_get_imp_tbl_data_slots(const AOTImportTable *tbl)
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_H_ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,142 +17,144 @@ typedef AOTIntCond IntCond;
|
|||
typedef AOTFloatCond FloatCond;
|
||||
|
||||
typedef enum IntArithmetic {
|
||||
INT_ADD = 0,
|
||||
INT_SUB,
|
||||
INT_MUL,
|
||||
INT_DIV_S,
|
||||
INT_DIV_U,
|
||||
INT_REM_S,
|
||||
INT_REM_U
|
||||
INT_ADD = 0,
|
||||
INT_SUB,
|
||||
INT_MUL,
|
||||
INT_DIV_S,
|
||||
INT_DIV_U,
|
||||
INT_REM_S,
|
||||
INT_REM_U
|
||||
} IntArithmetic;
|
||||
|
||||
typedef enum V128Arithmetic {
|
||||
V128_ADD = 0,
|
||||
V128_SUB,
|
||||
V128_MUL,
|
||||
V128_DIV,
|
||||
V128_NEG,
|
||||
V128_MIN,
|
||||
V128_MAX,
|
||||
V128_ADD = 0,
|
||||
V128_SUB,
|
||||
V128_MUL,
|
||||
V128_DIV,
|
||||
V128_NEG,
|
||||
V128_MIN,
|
||||
V128_MAX,
|
||||
} V128Arithmetic;
|
||||
|
||||
typedef enum IntBitwise {
|
||||
INT_AND = 0,
|
||||
INT_OR,
|
||||
INT_XOR,
|
||||
INT_AND = 0,
|
||||
INT_OR,
|
||||
INT_XOR,
|
||||
} IntBitwise;
|
||||
|
||||
typedef enum V128Bitwise {
|
||||
V128_NOT,
|
||||
V128_AND,
|
||||
V128_ANDNOT,
|
||||
V128_OR,
|
||||
V128_XOR,
|
||||
V128_BITSELECT,
|
||||
V128_NOT,
|
||||
V128_AND,
|
||||
V128_ANDNOT,
|
||||
V128_OR,
|
||||
V128_XOR,
|
||||
V128_BITSELECT,
|
||||
} V128Bitwise;
|
||||
|
||||
typedef enum IntShift {
|
||||
INT_SHL = 0,
|
||||
INT_SHR_S,
|
||||
INT_SHR_U,
|
||||
INT_ROTL,
|
||||
INT_ROTR
|
||||
INT_SHL = 0,
|
||||
INT_SHR_S,
|
||||
INT_SHR_U,
|
||||
INT_ROTL,
|
||||
INT_ROTR
|
||||
} IntShift;
|
||||
|
||||
typedef enum FloatMath {
|
||||
FLOAT_ABS = 0,
|
||||
FLOAT_NEG,
|
||||
FLOAT_CEIL,
|
||||
FLOAT_FLOOR,
|
||||
FLOAT_TRUNC,
|
||||
FLOAT_NEAREST,
|
||||
FLOAT_SQRT
|
||||
FLOAT_ABS = 0,
|
||||
FLOAT_NEG,
|
||||
FLOAT_CEIL,
|
||||
FLOAT_FLOOR,
|
||||
FLOAT_TRUNC,
|
||||
FLOAT_NEAREST,
|
||||
FLOAT_SQRT
|
||||
} FloatMath;
|
||||
|
||||
typedef enum FloatArithmetic {
|
||||
FLOAT_ADD = 0,
|
||||
FLOAT_SUB,
|
||||
FLOAT_MUL,
|
||||
FLOAT_DIV,
|
||||
FLOAT_MIN,
|
||||
FLOAT_MAX,
|
||||
FLOAT_ADD = 0,
|
||||
FLOAT_SUB,
|
||||
FLOAT_MUL,
|
||||
FLOAT_DIV,
|
||||
FLOAT_MIN,
|
||||
FLOAT_MAX,
|
||||
} FloatArithmetic;
|
||||
|
||||
static inline bool
|
||||
check_type_compatible(uint8 src_type, uint8 dst_type)
|
||||
{
|
||||
if (src_type == dst_type) {
|
||||
return true;
|
||||
}
|
||||
if (src_type == dst_type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ext i1 to i32 */
|
||||
if (src_type == VALUE_TYPE_I1 && dst_type == VALUE_TYPE_I32) {
|
||||
return true;
|
||||
}
|
||||
/* ext i1 to i32 */
|
||||
if (src_type == VALUE_TYPE_I1 && dst_type == VALUE_TYPE_I32) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* i32 <==> func.ref, i32 <==> extern.ref */
|
||||
if (src_type == VALUE_TYPE_I32
|
||||
&& (dst_type == VALUE_TYPE_EXTERNREF
|
||||
|| dst_type == VALUE_TYPE_FUNCREF)) {
|
||||
return true;
|
||||
}
|
||||
/* i32 <==> func.ref, i32 <==> extern.ref */
|
||||
if (src_type == VALUE_TYPE_I32
|
||||
&& (dst_type == VALUE_TYPE_EXTERNREF
|
||||
|| dst_type == VALUE_TYPE_FUNCREF)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dst_type == VALUE_TYPE_I32
|
||||
&& (src_type == VALUE_TYPE_FUNCREF
|
||||
|| src_type == VALUE_TYPE_EXTERNREF)) {
|
||||
return true;
|
||||
}
|
||||
if (dst_type == VALUE_TYPE_I32
|
||||
&& (src_type == VALUE_TYPE_FUNCREF
|
||||
|| src_type == VALUE_TYPE_EXTERNREF)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define CHECK_STACK() do { \
|
||||
if (!func_ctx->block_stack.block_list_end) { \
|
||||
aot_set_last_error("WASM block stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (!func_ctx->block_stack.block_list_end-> \
|
||||
value_stack.value_list_end) { \
|
||||
aot_set_last_error("WASM data stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_STACK() \
|
||||
do { \
|
||||
if (!func_ctx->block_stack.block_list_end) { \
|
||||
aot_set_last_error("WASM block stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (!func_ctx->block_stack.block_list_end->value_stack \
|
||||
.value_list_end) { \
|
||||
aot_set_last_error("WASM data stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define POP(llvm_value, value_type) do { \
|
||||
AOTValue *aot_value; \
|
||||
CHECK_STACK(); \
|
||||
aot_value = aot_value_stack_pop \
|
||||
(&func_ctx->block_stack.block_list_end->value_stack); \
|
||||
if (!check_type_compatible(aot_value->type, \
|
||||
value_type)) { \
|
||||
aot_set_last_error("invalid WASM stack data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (aot_value->type == value_type) \
|
||||
llvm_value = aot_value->value; \
|
||||
else { \
|
||||
if (aot_value->type == VALUE_TYPE_I1) { \
|
||||
if (!(llvm_value = LLVMBuildZExt(comp_ctx->builder, \
|
||||
aot_value->value, I32_TYPE, "i1toi32"))) { \
|
||||
aot_set_last_error("invalid WASM stack " \
|
||||
"data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
bh_assert(aot_value->type == VALUE_TYPE_I32 \
|
||||
|| aot_value->type == VALUE_TYPE_FUNCREF \
|
||||
|| aot_value->type == VALUE_TYPE_EXTERNREF); \
|
||||
bh_assert(value_type == VALUE_TYPE_I32 \
|
||||
|| value_type == VALUE_TYPE_FUNCREF \
|
||||
|| value_type == VALUE_TYPE_EXTERNREF); \
|
||||
llvm_value = aot_value->value; \
|
||||
} \
|
||||
} \
|
||||
wasm_runtime_free(aot_value); \
|
||||
} while (0)
|
||||
#define POP(llvm_value, value_type) \
|
||||
do { \
|
||||
AOTValue *aot_value; \
|
||||
CHECK_STACK(); \
|
||||
aot_value = aot_value_stack_pop( \
|
||||
&func_ctx->block_stack.block_list_end->value_stack); \
|
||||
if (!check_type_compatible(aot_value->type, value_type)) { \
|
||||
aot_set_last_error("invalid WASM stack data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (aot_value->type == value_type) \
|
||||
llvm_value = aot_value->value; \
|
||||
else { \
|
||||
if (aot_value->type == VALUE_TYPE_I1) { \
|
||||
if (!(llvm_value = \
|
||||
LLVMBuildZExt(comp_ctx->builder, aot_value->value, \
|
||||
I32_TYPE, "i1toi32"))) { \
|
||||
aot_set_last_error("invalid WASM stack " \
|
||||
"data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
bh_assert(aot_value->type == VALUE_TYPE_I32 \
|
||||
|| aot_value->type == VALUE_TYPE_FUNCREF \
|
||||
|| aot_value->type == VALUE_TYPE_EXTERNREF); \
|
||||
bh_assert(value_type == VALUE_TYPE_I32 \
|
||||
|| value_type == VALUE_TYPE_FUNCREF \
|
||||
|| value_type == VALUE_TYPE_EXTERNREF); \
|
||||
llvm_value = aot_value->value; \
|
||||
} \
|
||||
} \
|
||||
wasm_runtime_free(aot_value); \
|
||||
} while (0)
|
||||
|
||||
#define POP_I32(v) POP(v, VALUE_TYPE_I32)
|
||||
#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_EXTERNREF(v) POP(v, VALUE_TYPE_EXTERNREF)
|
||||
|
||||
#define POP_COND(llvm_value) do { \
|
||||
AOTValue *aot_value; \
|
||||
CHECK_STACK(); \
|
||||
aot_value = aot_value_stack_pop \
|
||||
(&func_ctx->block_stack.block_list_end->value_stack); \
|
||||
if (aot_value->type != VALUE_TYPE_I1 \
|
||||
&& aot_value->type != VALUE_TYPE_I32) { \
|
||||
aot_set_last_error("invalid WASM stack data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (aot_value->type == VALUE_TYPE_I1) \
|
||||
llvm_value = aot_value->value; \
|
||||
else { \
|
||||
if (!(llvm_value = LLVMBuildICmp(comp_ctx->builder, \
|
||||
LLVMIntNE, aot_value->value, I32_ZERO, \
|
||||
"i1_cond"))){ \
|
||||
aot_set_last_error("llvm build trunc failed."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
wasm_runtime_free(aot_value); \
|
||||
} while (0)
|
||||
#define POP_COND(llvm_value) \
|
||||
do { \
|
||||
AOTValue *aot_value; \
|
||||
CHECK_STACK(); \
|
||||
aot_value = aot_value_stack_pop( \
|
||||
&func_ctx->block_stack.block_list_end->value_stack); \
|
||||
if (aot_value->type != VALUE_TYPE_I1 \
|
||||
&& aot_value->type != VALUE_TYPE_I32) { \
|
||||
aot_set_last_error("invalid WASM stack data type."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
if (aot_value->type == VALUE_TYPE_I1) \
|
||||
llvm_value = aot_value->value; \
|
||||
else { \
|
||||
if (!(llvm_value = \
|
||||
LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, \
|
||||
aot_value->value, I32_ZERO, "i1_cond"))) { \
|
||||
aot_set_last_error("llvm build trunc failed."); \
|
||||
wasm_runtime_free(aot_value); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
wasm_runtime_free(aot_value); \
|
||||
} while (0)
|
||||
|
||||
#define PUSH(llvm_value, value_type) do { \
|
||||
AOTValue *aot_value; \
|
||||
if (!func_ctx->block_stack.block_list_end) { \
|
||||
aot_set_last_error("WASM block stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
aot_value = wasm_runtime_malloc(sizeof(AOTValue)); \
|
||||
if (!aot_value) { \
|
||||
aot_set_last_error("allocate memory failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
memset(aot_value, 0, sizeof(AOTValue)); \
|
||||
aot_value->type = value_type; \
|
||||
aot_value->value = llvm_value; \
|
||||
aot_value_stack_push \
|
||||
(&func_ctx->block_stack.block_list_end->value_stack,\
|
||||
aot_value); \
|
||||
} while (0)
|
||||
#define PUSH(llvm_value, value_type) \
|
||||
do { \
|
||||
AOTValue *aot_value; \
|
||||
if (!func_ctx->block_stack.block_list_end) { \
|
||||
aot_set_last_error("WASM block stack underflow."); \
|
||||
goto fail; \
|
||||
} \
|
||||
aot_value = wasm_runtime_malloc(sizeof(AOTValue)); \
|
||||
if (!aot_value) { \
|
||||
aot_set_last_error("allocate memory failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
memset(aot_value, 0, sizeof(AOTValue)); \
|
||||
aot_value->type = value_type; \
|
||||
aot_value->value = llvm_value; \
|
||||
aot_value_stack_push( \
|
||||
&func_ctx->block_stack.block_list_end->value_stack, aot_value); \
|
||||
} while (0)
|
||||
|
||||
#define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32)
|
||||
#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 LLVM_CONST(name) (comp_ctx->llvm_consts.name)
|
||||
#define I8_ZERO LLVM_CONST(i8_zero)
|
||||
#define I32_ZERO LLVM_CONST(i32_zero)
|
||||
#define I64_ZERO LLVM_CONST(i64_zero)
|
||||
#define F32_ZERO LLVM_CONST(f32_zero)
|
||||
#define F64_ZERO LLVM_CONST(f64_zero)
|
||||
#define I32_ONE LLVM_CONST(i32_one)
|
||||
#define I32_TWO LLVM_CONST(i32_two)
|
||||
#define I32_THREE LLVM_CONST(i32_three)
|
||||
#define I32_FOUR LLVM_CONST(i32_four)
|
||||
#define I32_FIVE LLVM_CONST(i32_five)
|
||||
#define I32_SIX LLVM_CONST(i32_six)
|
||||
#define I32_SEVEN LLVM_CONST(i32_seven)
|
||||
#define I32_EIGHT LLVM_CONST(i32_eight)
|
||||
#define I8_ZERO LLVM_CONST(i8_zero)
|
||||
#define I32_ZERO LLVM_CONST(i32_zero)
|
||||
#define I64_ZERO LLVM_CONST(i64_zero)
|
||||
#define F32_ZERO LLVM_CONST(f32_zero)
|
||||
#define F64_ZERO LLVM_CONST(f64_zero)
|
||||
#define I32_ONE LLVM_CONST(i32_one)
|
||||
#define I32_TWO LLVM_CONST(i32_two)
|
||||
#define I32_THREE LLVM_CONST(i32_three)
|
||||
#define I32_FOUR LLVM_CONST(i32_four)
|
||||
#define I32_FIVE LLVM_CONST(i32_five)
|
||||
#define I32_SIX LLVM_CONST(i32_six)
|
||||
#define I32_SEVEN LLVM_CONST(i32_seven)
|
||||
#define I32_EIGHT LLVM_CONST(i32_eight)
|
||||
#define I32_NEG_ONE LLVM_CONST(i32_neg_one)
|
||||
#define I64_NEG_ONE LLVM_CONST(i64_neg_one)
|
||||
#define I32_MIN LLVM_CONST(i32_min)
|
||||
#define I64_MIN LLVM_CONST(i64_min)
|
||||
#define I32_31 LLVM_CONST(i32_31)
|
||||
#define I32_32 LLVM_CONST(i32_32)
|
||||
#define I64_63 LLVM_CONST(i64_63)
|
||||
#define I64_64 LLVM_CONST(i64_64)
|
||||
#define REF_NULL I32_NEG_ONE
|
||||
#define I32_MIN LLVM_CONST(i32_min)
|
||||
#define I64_MIN LLVM_CONST(i64_min)
|
||||
#define I32_31 LLVM_CONST(i32_31)
|
||||
#define I32_32 LLVM_CONST(i32_32)
|
||||
#define I64_63 LLVM_CONST(i64_63)
|
||||
#define I64_64 LLVM_CONST(i64_64)
|
||||
#define REF_NULL I32_NEG_ONE
|
||||
|
||||
#define V128_TYPE comp_ctx->basic_types.v128_type
|
||||
#define V128_PTR_TYPE comp_ctx->basic_types.v128_ptr_type
|
||||
#define V128_TYPE comp_ctx->basic_types.v128_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_i16x8_TYPE comp_ctx->basic_types.i16x8_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_f64x2_ZERO LLVM_CONST(f64x2_vec_zero)
|
||||
|
||||
#define TO_V128_i8x16(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_i8x16_TYPE, "i8x16_val")
|
||||
#define TO_V128_i16x8(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_i16x8_TYPE, "i16x8_val")
|
||||
#define TO_V128_i32x4(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_i32x4_TYPE, "i32x4_val")
|
||||
#define TO_V128_i64x2(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_i64x2_TYPE, "i64x2_val")
|
||||
#define TO_V128_f32x4(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_f32x4_TYPE, "f32x4_val")
|
||||
#define TO_V128_f64x2(v) LLVMBuildBitCast(comp_ctx->builder, v, \
|
||||
V128_f64x2_TYPE, "f64x2_val")
|
||||
#define TO_V128_i8x16(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_i8x16_TYPE, "i8x16_val")
|
||||
#define TO_V128_i16x8(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_i16x8_TYPE, "i16x8_val")
|
||||
#define TO_V128_i32x4(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_i32x4_TYPE, "i32x4_val")
|
||||
#define TO_V128_i64x2(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_i64x2_TYPE, "i64x2_val")
|
||||
#define TO_V128_f32x4(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_f32x4_TYPE, "f32x4_val")
|
||||
#define TO_V128_f64x2(v) \
|
||||
LLVMBuildBitCast(comp_ctx->builder, v, V128_f64x2_TYPE, "f64x2_val")
|
||||
|
||||
#define CHECK_LLVM_CONST(v) do { \
|
||||
if (!v) { \
|
||||
aot_set_last_error("create llvm const failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_LLVM_CONST(v) \
|
||||
do { \
|
||||
if (!v) { \
|
||||
aot_set_last_error("create llvm const failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define GET_AOT_FUNCTION(name, argc) do { \
|
||||
if (!(func_type = LLVMFunctionType(ret_type, param_types, \
|
||||
argc, 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 (!(func_ptr_type = LLVMPointerType(func_type, 0))) { \
|
||||
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))) { \
|
||||
aot_set_last_error("create LLVM value failed."); \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
char *func_name = #name; \
|
||||
/* AOT mode, delcare the function */ \
|
||||
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \
|
||||
&& !(func = LLVMAddFunction(comp_ctx->module, \
|
||||
func_name, func_type))) { \
|
||||
aot_set_last_error("llvm add function failed."); \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define GET_AOT_FUNCTION(name, argc) \
|
||||
do { \
|
||||
if (!(func_type = \
|
||||
LLVMFunctionType(ret_type, param_types, argc, 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 (!(func_ptr_type = LLVMPointerType(func_type, 0))) { \
|
||||
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))) { \
|
||||
aot_set_last_error("create LLVM value failed."); \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
char *func_name = #name; \
|
||||
/* AOT mode, delcare the function */ \
|
||||
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name)) \
|
||||
&& !(func = LLVMAddFunction(comp_ctx->module, func_name, \
|
||||
func_type))) { \
|
||||
aot_set_last_error("llvm add function failed."); \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
bool
|
||||
aot_compile_wasm(AOTCompContext *comp_ctx);
|
||||
|
@ -339,27 +344,23 @@ bool
|
|||
aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name);
|
||||
|
||||
bool
|
||||
aot_emit_aot_file(AOTCompContext *comp_ctx,
|
||||
AOTCompData *comp_data,
|
||||
aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||
const char *file_name);
|
||||
|
||||
uint8*
|
||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
||||
AOTCompData *comp_data,
|
||||
uint8 *
|
||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||
uint32 *p_aot_file_size);
|
||||
|
||||
bool
|
||||
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,
|
||||
uint32 opt_level, uint32 size_level,
|
||||
char *error_buf, uint32 error_buf_size,
|
||||
uint32 *p_aot_file_size);
|
||||
uint32 opt_level, uint32 size_level, char *error_buf,
|
||||
uint32 error_buf_size, uint32 *p_aot_file_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _AOT_COMPILER_H_ */
|
||||
|
||||
|
|
|
@ -6,19 +6,24 @@
|
|||
#include "aot_compiler.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
#define PUT_U64_TO_ADDR(addr, value) do { \
|
||||
union { uint64 val; uint32 parts[2]; } u; \
|
||||
u.val = (value); \
|
||||
((uint32*)(addr))[0] = u.parts[0]; \
|
||||
((uint32*)(addr))[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
#define PUT_U64_TO_ADDR(addr, value) \
|
||||
do { \
|
||||
union { \
|
||||
uint64 val; \
|
||||
uint32 parts[2]; \
|
||||
} u; \
|
||||
u.val = (value); \
|
||||
((uint32 *)(addr))[0] = u.parts[0]; \
|
||||
((uint32 *)(addr))[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_SIZE(size) do { \
|
||||
if (size == (uint32)-1) { \
|
||||
aot_set_last_error("get symbol size failed."); \
|
||||
return (uint32)-1; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_SIZE(size) \
|
||||
do { \
|
||||
if (size == (uint32)-1) { \
|
||||
aot_set_last_error("get symbol size failed."); \
|
||||
return (uint32)-1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Internal function in object file */
|
||||
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)
|
||||
+ byte count (4 bytes) + bytes */
|
||||
uint32 total_size =
|
||||
(uint32)(sizeof(uint32) + sizeof(uint64)
|
||||
+ sizeof(uint32) + mem_init_data->byte_count);
|
||||
uint32 total_size = (uint32)(sizeof(uint32) + sizeof(uint64)
|
||||
+ sizeof(uint32) + mem_init_data->byte_count);
|
||||
|
||||
/* bulk_memory enabled:
|
||||
is_passive (4 bytes) + memory_index (4 bytes)
|
||||
|
@ -173,8 +177,7 @@ get_mem_info_size(AOTCompData *comp_data)
|
|||
{
|
||||
/* import_memory_size + memory_size
|
||||
+ init_data_count + init_data_list */
|
||||
return get_import_memory_size(comp_data)
|
||||
+ get_memory_size(comp_data)
|
||||
return get_import_memory_size(comp_data) + get_memory_size(comp_data)
|
||||
+ (uint32)sizeof(uint32)
|
||||
+ get_mem_init_data_list_size(comp_data->mem_init_data_list,
|
||||
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
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
return (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32)
|
||||
|
@ -238,8 +242,7 @@ get_import_table_size(AOTCompData *comp_data)
|
|||
* ------------------------------
|
||||
*/
|
||||
return (uint32)(sizeof(uint32)
|
||||
+ comp_data->import_table_count
|
||||
* (sizeof(uint32) * 3));
|
||||
+ comp_data->import_table_count * (sizeof(uint32) * 3));
|
||||
}
|
||||
|
||||
static uint32
|
||||
|
@ -257,8 +260,7 @@ get_table_size(AOTCompData *comp_data)
|
|||
* ------------------------------
|
||||
*/
|
||||
return (uint32)(sizeof(uint32)
|
||||
+ comp_data->table_count
|
||||
* (sizeof(uint32) * 5));
|
||||
+ comp_data->table_count * (sizeof(uint32) * 5));
|
||||
}
|
||||
|
||||
static uint32
|
||||
|
@ -294,8 +296,8 @@ static uint32
|
|||
get_func_type_size(AOTFuncType *func_type)
|
||||
{
|
||||
/* param count + result count + types */
|
||||
return (uint32)sizeof(uint32) * 2
|
||||
+ func_type->param_count + func_type->result_count;
|
||||
return (uint32)sizeof(uint32) * 2 + func_type->param_count
|
||||
+ func_type->result_count;
|
||||
}
|
||||
|
||||
static uint32
|
||||
|
@ -324,8 +326,8 @@ static uint32
|
|||
get_import_global_size(AOTImportGlobal *import_global)
|
||||
{
|
||||
/* type (1 byte) + is_mutable (1 byte) + module_name + global_name */
|
||||
uint32 size = (uint32)sizeof(uint8) * 2
|
||||
+ get_string_size(import_global->module_name);
|
||||
uint32 size =
|
||||
(uint32)sizeof(uint8) * 2 + get_string_size(import_global->module_name);
|
||||
size = align_uint(size, 2);
|
||||
size += get_string_size(import_global->global_name);
|
||||
return size;
|
||||
|
@ -385,24 +387,22 @@ get_global_info_size(AOTCompData *comp_data)
|
|||
{
|
||||
/* global count + globals */
|
||||
return (uint32)sizeof(uint32)
|
||||
+ get_globals_size(comp_data->globals,
|
||||
comp_data->global_count);
|
||||
+ get_globals_size(comp_data->globals, comp_data->global_count);
|
||||
}
|
||||
|
||||
static uint32
|
||||
get_import_func_size(AOTImportFunc *import_func)
|
||||
{
|
||||
/* type index (2 bytes) + module_name + func_name */
|
||||
uint32 size = (uint32)sizeof(uint16)
|
||||
+ get_string_size(import_func->module_name);
|
||||
uint32 size =
|
||||
(uint32)sizeof(uint16) + get_string_size(import_func->module_name);
|
||||
size = align_uint(size, 2);
|
||||
size += get_string_size(import_func->func_name);
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32
|
||||
get_import_funcs_size(AOTImportFunc *import_funcs,
|
||||
uint32 import_func_count)
|
||||
get_import_funcs_size(AOTImportFunc *import_funcs, uint32 import_func_count)
|
||||
{
|
||||
AOTImportFunc *import_func = import_funcs;
|
||||
uint32 size = 0, i;
|
||||
|
@ -493,7 +493,8 @@ get_init_data_section_size(AOTCompData *comp_data, AOTObjectData *obj_data)
|
|||
static uint32
|
||||
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
|
||||
|
@ -525,7 +526,7 @@ get_exports_size(AOTExport *exports, uint32 export_count)
|
|||
AOTExport *export = exports;
|
||||
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 += get_export_size(export);
|
||||
}
|
||||
|
@ -549,15 +550,14 @@ get_relocation_size(AOTRelocation *relocation, bool is_32bin)
|
|||
if (is_32bin)
|
||||
size = sizeof(uint32) * 2; /* offset and addend */
|
||||
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); /* symbol name index */
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32
|
||||
get_relocations_size(AOTRelocation *relocations,
|
||||
uint32 relocation_count,
|
||||
get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
|
||||
bool is_32bin)
|
||||
{
|
||||
AOTRelocation *relocation = relocations;
|
||||
|
@ -571,23 +571,20 @@ get_relocations_size(AOTRelocation *relocations,
|
|||
}
|
||||
|
||||
static uint32
|
||||
get_relocation_group_size(AOTRelocationGroup *relocation_group,
|
||||
bool is_32bin)
|
||||
get_relocation_group_size(AOTRelocationGroup *relocation_group, bool is_32bin)
|
||||
{
|
||||
uint32 size = 0;
|
||||
/* section name index + relocation count + relocations */
|
||||
size += (uint32)sizeof(uint32);
|
||||
size += (uint32)sizeof(uint32);
|
||||
size += get_relocations_size(relocation_group->relocations,
|
||||
relocation_group->relocation_count,
|
||||
is_32bin);
|
||||
relocation_group->relocation_count, is_32bin);
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32
|
||||
get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
|
||||
uint32 relocation_group_count,
|
||||
bool is_32bin)
|
||||
uint32 relocation_group_count, bool is_32bin)
|
||||
{
|
||||
AOTRelocationGroup *relocation_group = relocation_groups;
|
||||
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,
|
||||
create if not exits, -1 if failed */
|
||||
static uint32
|
||||
get_relocation_symbol_index(const char *symbol_name,
|
||||
bool *is_new,
|
||||
get_relocation_symbol_index(const char *symbol_name, bool *is_new,
|
||||
AOTSymbolList *symbol_list)
|
||||
{
|
||||
AOTSymbolNode *sym;
|
||||
|
@ -618,7 +614,7 @@ get_relocation_symbol_index(const char *symbol_name,
|
|||
}
|
||||
|
||||
sym = sym->next;
|
||||
index ++;
|
||||
index++;
|
||||
}
|
||||
|
||||
/* 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 = sym;
|
||||
}
|
||||
symbol_list->len ++;
|
||||
symbol_list->len++;
|
||||
|
||||
if (is_new)
|
||||
*is_new = true;
|
||||
|
@ -652,7 +648,8 @@ get_relocation_symbol_size(AOTRelocation *relocation,
|
|||
uint32 size = 0, index = 0;
|
||||
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);
|
||||
|
||||
if (is_new) {
|
||||
|
@ -666,8 +663,7 @@ get_relocation_symbol_size(AOTRelocation *relocation,
|
|||
}
|
||||
|
||||
static uint32
|
||||
get_relocations_symbol_size(AOTRelocation *relocations,
|
||||
uint32 relocation_count,
|
||||
get_relocations_symbol_size(AOTRelocation *relocations, uint32 relocation_count,
|
||||
AOTSymbolList *symbol_list)
|
||||
{
|
||||
AOTRelocation *relocation = relocations;
|
||||
|
@ -689,8 +685,7 @@ get_relocation_group_symbol_size(AOTRelocationGroup *relocation_group,
|
|||
uint32 size = 0, index = 0, curr_size;
|
||||
bool is_new = false;
|
||||
|
||||
index = get_relocation_symbol_index(relocation_group->section_name,
|
||||
&is_new,
|
||||
index = get_relocation_symbol_index(relocation_group->section_name, &is_new,
|
||||
symbol_list);
|
||||
CHECK_SIZE(index);
|
||||
|
||||
|
@ -720,8 +715,8 @@ get_relocation_groups_symbol_size(AOTRelocationGroup *relocation_groups,
|
|||
uint32 size = 0, curr_size, i;
|
||||
|
||||
for (i = 0; i < relocation_group_count; i++, relocation_group++) {
|
||||
curr_size = get_relocation_group_symbol_size(relocation_group,
|
||||
symbol_list);
|
||||
curr_size =
|
||||
get_relocation_group_symbol_size(relocation_group, symbol_list);
|
||||
CHECK_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 */
|
||||
if (obj_data->symbol_list.len > 0) {
|
||||
symbol_table_size =
|
||||
get_symbol_size_from_symbol_list(&obj_data->symbol_list);
|
||||
get_symbol_size_from_symbol_list(&obj_data->symbol_list);
|
||||
}
|
||||
else {
|
||||
symbol_table_size =
|
||||
get_relocation_groups_symbol_size(relocation_groups,
|
||||
relocation_group_count,
|
||||
&obj_data->symbol_list);
|
||||
symbol_table_size = get_relocation_groups_symbol_size(
|
||||
relocation_groups, relocation_group_count, &obj_data->symbol_list);
|
||||
}
|
||||
CHECK_SIZE(symbol_table_size);
|
||||
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
|
||||
+ sizeof(uint32) + symbol_table_size);
|
||||
}
|
||||
|
@ -901,9 +895,9 @@ static void
|
|||
exchange_uint128(uint8 *pData)
|
||||
{
|
||||
/* swap high 64bit and low 64bit */
|
||||
uint64 value = *(uint64*)pData;
|
||||
*(uint64*)pData = *(uint64*)(pData + 8);
|
||||
*(uint64*)(pData + 8) = value;
|
||||
uint64 value = *(uint64 *)pData;
|
||||
*(uint64 *)pData = *(uint64 *)(pData + 8);
|
||||
*(uint64 *)(pData + 8) = value;
|
||||
/* exchange high 64bit */
|
||||
exchange_uint64(pData);
|
||||
/* exchange low 64bit */
|
||||
|
@ -917,68 +911,76 @@ static union {
|
|||
|
||||
#define is_little_endian() (__ue.b == 1)
|
||||
|
||||
#define CHECK_BUF(length) do { \
|
||||
if (buf + offset + length > buf_end) { \
|
||||
aot_set_last_error("buf overflow"); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_BUF(length) \
|
||||
do { \
|
||||
if (buf + offset + length > buf_end) { \
|
||||
aot_set_last_error("buf overflow"); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_U8(v) do { \
|
||||
CHECK_BUF(1); \
|
||||
*(uint8*)(buf + offset) = (uint8)v; \
|
||||
offset++; \
|
||||
} while (0)
|
||||
#define EMIT_U8(v) \
|
||||
do { \
|
||||
CHECK_BUF(1); \
|
||||
*(uint8 *)(buf + offset) = (uint8)v; \
|
||||
offset++; \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_U16(v) do { \
|
||||
uint16 t = (uint16)v; \
|
||||
CHECK_BUF(2); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint16((uint8*)&t); \
|
||||
*(uint16*)(buf + offset) = t; \
|
||||
offset += (uint32)sizeof(uint16); \
|
||||
} while (0)
|
||||
#define EMIT_U16(v) \
|
||||
do { \
|
||||
uint16 t = (uint16)v; \
|
||||
CHECK_BUF(2); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint16((uint8 *)&t); \
|
||||
*(uint16 *)(buf + offset) = t; \
|
||||
offset += (uint32)sizeof(uint16); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_U32(v) do { \
|
||||
uint32 t = (uint32)v; \
|
||||
CHECK_BUF(4); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint32((uint8*)&t); \
|
||||
*(uint32*)(buf + offset) = t; \
|
||||
offset += (uint32)sizeof(uint32); \
|
||||
} while (0)
|
||||
#define EMIT_U32(v) \
|
||||
do { \
|
||||
uint32 t = (uint32)v; \
|
||||
CHECK_BUF(4); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint32((uint8 *)&t); \
|
||||
*(uint32 *)(buf + offset) = t; \
|
||||
offset += (uint32)sizeof(uint32); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_U64(v) do { \
|
||||
uint64 t = (uint64)v; \
|
||||
CHECK_BUF(8); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint64((uint8*)&t); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
} while (0)
|
||||
#define EMIT_U64(v) \
|
||||
do { \
|
||||
uint64 t = (uint64)v; \
|
||||
CHECK_BUF(8); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint64((uint8 *)&t); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_V128(v) do { \
|
||||
uint64 *t = (uint64*)v.i64x2; \
|
||||
CHECK_BUF(16); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint128((uint8 *)t); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t[0]); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t[1]); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
} while (0)
|
||||
#define EMIT_V128(v) \
|
||||
do { \
|
||||
uint64 *t = (uint64 *)v.i64x2; \
|
||||
CHECK_BUF(16); \
|
||||
if (!is_little_endian()) \
|
||||
exchange_uint128((uint8 *)t); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t[0]); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
PUT_U64_TO_ADDR(buf + offset, t[1]); \
|
||||
offset += (uint32)sizeof(uint64); \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_BUF(v, len) do { \
|
||||
CHECK_BUF(len); \
|
||||
memcpy(buf + offset, v, len); \
|
||||
offset += len; \
|
||||
} while (0)
|
||||
#define EMIT_BUF(v, len) \
|
||||
do { \
|
||||
CHECK_BUF(len); \
|
||||
memcpy(buf + offset, v, len); \
|
||||
offset += len; \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_STR(s) do { \
|
||||
uint32 str_len = (uint32)strlen(s); \
|
||||
EMIT_U16(str_len); \
|
||||
EMIT_BUF(s, str_len); \
|
||||
} while (0)
|
||||
#define EMIT_STR(s) \
|
||||
do { \
|
||||
uint32 str_len = (uint32)strlen(s); \
|
||||
EMIT_U16(str_len); \
|
||||
EMIT_BUF(s, str_len); \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
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)
|
||||
|| !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_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_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;
|
||||
|
||||
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(export_count);
|
||||
|
||||
for (i = 0; i < export_count; i++, export++) {
|
||||
for (i = 0; i < export_count; i++, export ++) {
|
||||
offset = align_uint(offset, 4);
|
||||
EMIT_U32(export->index);
|
||||
EMIT_U8(export->kind);
|
||||
|
@ -1440,7 +1444,8 @@ aot_emit_export_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
|
||||
static bool
|
||||
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 offset = *p_offset;
|
||||
|
@ -1450,7 +1455,7 @@ aot_emit_relocation_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
|
||||
/* emit symbol offsets */
|
||||
sym = (AOTSymbolNode *)(obj_data->symbol_list.head);
|
||||
while(sym) {
|
||||
while (sym) {
|
||||
EMIT_U32(symbol_offset);
|
||||
/* string_len + str[0 .. string_len - 1] */
|
||||
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(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);
|
||||
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 int32 I32;
|
||||
typedef int32 I32;
|
||||
typedef uint16 U16;
|
||||
typedef uint8 U8;
|
||||
typedef uint8 U8;
|
||||
|
||||
struct coff_hdr {
|
||||
U16 u16Machine;
|
||||
|
@ -1577,35 +1583,35 @@ struct coff_hdr {
|
|||
U16 u16Characs;
|
||||
};
|
||||
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
|
||||
#define AOT_COFF_BIN_TYPE 6
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef uint32 elf32_word;
|
||||
typedef int32 elf32_sword;
|
||||
typedef uint16 elf32_half;
|
||||
typedef uint32 elf32_off;
|
||||
typedef uint32 elf32_addr;
|
||||
typedef uint32 elf32_word;
|
||||
typedef int32 elf32_sword;
|
||||
typedef uint16 elf32_half;
|
||||
typedef uint32 elf32_off;
|
||||
typedef uint32 elf32_addr;
|
||||
|
||||
struct elf32_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
|
||||
elf32_half e_type; /* file type */
|
||||
elf32_half e_machine; /* target machine */
|
||||
elf32_word e_version; /* file version */
|
||||
elf32_addr e_entry; /* start address */
|
||||
elf32_off e_phoff; /* phdr file offset */
|
||||
elf32_off e_shoff; /* shdr file offset */
|
||||
elf32_word e_flags; /* file flags */
|
||||
elf32_half e_ehsize; /* sizeof ehdr */
|
||||
elf32_half e_phentsize; /* sizeof phdr */
|
||||
elf32_half e_phnum; /* number phdrs */
|
||||
elf32_half e_shentsize; /* sizeof shdr */
|
||||
elf32_half e_shnum; /* number shdrs */
|
||||
elf32_half e_shstrndx; /* shdr string index */
|
||||
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
|
||||
elf32_half e_type; /* file type */
|
||||
elf32_half e_machine; /* target machine */
|
||||
elf32_word e_version; /* file version */
|
||||
elf32_addr e_entry; /* start address */
|
||||
elf32_off e_phoff; /* phdr file offset */
|
||||
elf32_off e_shoff; /* shdr file offset */
|
||||
elf32_word e_flags; /* file flags */
|
||||
elf32_half e_ehsize; /* sizeof ehdr */
|
||||
elf32_half e_phentsize; /* sizeof phdr */
|
||||
elf32_half e_phnum; /* number phdrs */
|
||||
elf32_half e_shentsize; /* sizeof shdr */
|
||||
elf32_half e_shnum; /* number shdrs */
|
||||
elf32_half e_shstrndx; /* shdr string index */
|
||||
};
|
||||
|
||||
struct elf32_rel {
|
||||
|
@ -1619,29 +1625,29 @@ struct elf32_rela {
|
|||
elf32_sword r_addend;
|
||||
} elf32_rela;
|
||||
|
||||
typedef uint32 elf64_word;
|
||||
typedef int32 elf64_sword;
|
||||
typedef uint64 elf64_xword;
|
||||
typedef int64 elf64_sxword;
|
||||
typedef uint16 elf64_half;
|
||||
typedef uint64 elf64_off;
|
||||
typedef uint64 elf64_addr;
|
||||
typedef uint32 elf64_word;
|
||||
typedef int32 elf64_sword;
|
||||
typedef uint64 elf64_xword;
|
||||
typedef int64 elf64_sxword;
|
||||
typedef uint16 elf64_half;
|
||||
typedef uint64 elf64_off;
|
||||
typedef uint64 elf64_addr;
|
||||
|
||||
struct elf64_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
|
||||
elf64_half e_type; /* file type */
|
||||
elf64_half e_machine; /* target machine */
|
||||
elf64_word e_version; /* file version */
|
||||
elf64_addr e_entry; /* start address */
|
||||
elf64_off e_phoff; /* phdr file offset */
|
||||
elf64_off e_shoff; /* shdr file offset */
|
||||
elf64_word e_flags; /* file flags */
|
||||
elf64_half e_ehsize; /* sizeof ehdr */
|
||||
elf64_half e_phentsize; /* sizeof phdr */
|
||||
elf64_half e_phnum; /* number phdrs */
|
||||
elf64_half e_shentsize; /* sizeof shdr */
|
||||
elf64_half e_shnum; /* number shdrs */
|
||||
elf64_half e_shstrndx; /* shdr string index */
|
||||
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
|
||||
elf64_half e_type; /* file type */
|
||||
elf64_half e_machine; /* target machine */
|
||||
elf64_word e_version; /* file version */
|
||||
elf64_addr e_entry; /* start address */
|
||||
elf64_off e_phoff; /* phdr file offset */
|
||||
elf64_off e_shoff; /* shdr file offset */
|
||||
elf64_word e_flags; /* file flags */
|
||||
elf64_half e_ehsize; /* sizeof ehdr */
|
||||
elf64_half e_phentsize; /* sizeof phdr */
|
||||
elf64_half e_phnum; /* number phdrs */
|
||||
elf64_half e_shentsize; /* sizeof shdr */
|
||||
elf64_half e_shnum; /* number shdrs */
|
||||
elf64_half e_shstrndx; /* shdr string index */
|
||||
};
|
||||
|
||||
typedef struct elf64_rel {
|
||||
|
@ -1655,14 +1661,14 @@ typedef struct elf64_rela {
|
|||
elf64_sxword r_addend;
|
||||
} elf64_rela;
|
||||
|
||||
|
||||
#define SET_TARGET_INFO(f, v, type, little) do { \
|
||||
type tmp = elf_header->v; \
|
||||
if ((little && !is_little_endian()) \
|
||||
|| (!little && is_little_endian())) \
|
||||
exchange_##type((uint8*)&tmp); \
|
||||
obj_data->target_info.f = tmp; \
|
||||
} while (0)
|
||||
#define SET_TARGET_INFO(f, v, type, little) \
|
||||
do { \
|
||||
type tmp = elf_header->v; \
|
||||
if ((little && !is_little_endian()) \
|
||||
|| (!little && is_little_endian())) \
|
||||
exchange_##type((uint8 *)&tmp); \
|
||||
obj_data->target_info.f = tmp; \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
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);
|
||||
uint32 elf_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf);
|
||||
|
||||
if (bin_type != LLVMBinaryTypeCOFF
|
||||
&& bin_type != LLVMBinaryTypeELF32L
|
||||
&& bin_type != LLVMBinaryTypeELF32B
|
||||
&& bin_type != LLVMBinaryTypeELF64L
|
||||
if (bin_type != LLVMBinaryTypeCOFF && bin_type != LLVMBinaryTypeELF32L
|
||||
&& bin_type != LLVMBinaryTypeELF32B && bin_type != LLVMBinaryTypeELF64L
|
||||
&& bin_type != LLVMBinaryTypeELF64B
|
||||
&& bin_type != LLVMBinaryTypeMachO32L
|
||||
&& 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;
|
||||
|
||||
if (bin_type == LLVMBinaryTypeCOFF) {
|
||||
struct coff_hdr * coff_header;
|
||||
struct coff_hdr *coff_header;
|
||||
|
||||
if (!elf_buf || elf_size < sizeof(struct coff_hdr)) {
|
||||
aot_set_last_error("invalid coff_hdr buffer.");
|
||||
|
@ -1747,7 +1751,6 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
strncpy(obj_data->target_info.arch, comp_ctx->target_arch,
|
||||
sizeof(obj_data->target_info.arch));
|
||||
|
||||
|
@ -1774,7 +1777,7 @@ aot_resolve_text(AOTObjectData *obj_data)
|
|||
return false;
|
||||
}
|
||||
while (
|
||||
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
|
||||
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
|
||||
if ((name = (char *)LLVMGetSectionName(sec_itr))
|
||||
&& !strcmp(name, ".text")) {
|
||||
obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
|
||||
|
@ -1800,7 +1803,8 @@ aot_resolve_literal(AOTObjectData *obj_data)
|
|||
return false;
|
||||
}
|
||||
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_size = (uint32)LLVMGetSectionSize(sec_itr);
|
||||
break;
|
||||
|
@ -1820,8 +1824,7 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
|
|||
{
|
||||
uint32 relocation_count = 0;
|
||||
|
||||
return (!strcmp(section_name, ".data")
|
||||
|| !strcmp(section_name, ".sdata")
|
||||
return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
|
||||
|| !strcmp(section_name, ".rodata")
|
||||
/* ".rodata.cst4/8/16/.." */
|
||||
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
|
||||
|
@ -1869,7 +1872,8 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
|
|||
|
||||
if (sections_count > 0) {
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -1880,7 +1884,8 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
|
|||
aot_set_last_error("llvm get section iterator failed.");
|
||||
return false;
|
||||
}
|
||||
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
|
||||
while (
|
||||
!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
|
||||
if ((name = (char *)LLVMGetSectionName(sec_itr))
|
||||
&& (is_data_section(sec_itr, name))) {
|
||||
data_section->name = name;
|
||||
|
@ -2020,14 +2025,16 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
|
|||
/* parse relocation addend from reloction content */
|
||||
if (has_addend) {
|
||||
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())
|
||||
exchange_uint32((uint8 *)&addend);
|
||||
relocation->relocation_addend = (uint64)addend;
|
||||
rela_content += sizeof(struct elf32_rela);
|
||||
}
|
||||
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())
|
||||
exchange_uint64((uint8 *)&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, ".LJTI")
|
||||
|| 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;
|
||||
if (!(contain_section
|
||||
= LLVMObjectFileCopySectionIterator(obj_data->binary))) {
|
||||
if (!(contain_section =
|
||||
LLVMObjectFileCopySectionIterator(obj_data->binary))) {
|
||||
aot_set_last_error("llvm get section iterator failed.");
|
||||
goto fail;
|
||||
}
|
||||
LLVMMoveToContainingSection(contain_section, rel_sym);
|
||||
if (LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, contain_section)) {
|
||||
if (LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary,
|
||||
contain_section)) {
|
||||
LLVMDisposeSectionIterator(contain_section);
|
||||
aot_set_last_error("llvm get containing section failed.");
|
||||
goto fail;
|
||||
}
|
||||
relocation->relocation_addend += LLVMGetSymbolAddress(rel_sym);
|
||||
relocation->symbol_name = (char *)LLVMGetSectionName(contain_section);
|
||||
relocation->symbol_name =
|
||||
(char *)LLVMGetSectionName(contain_section);
|
||||
LLVMDisposeSectionIterator(contain_section);
|
||||
}
|
||||
|
||||
|
@ -2151,7 +2161,8 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
|
|||
return true;
|
||||
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -2167,10 +2178,8 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
|
|||
if (is_relocation_section(sec_itr)) {
|
||||
name = (char *)LLVMGetSectionName(sec_itr);
|
||||
relocation_group->section_name = name;
|
||||
if (!aot_resolve_object_relocation_group(
|
||||
obj_data,
|
||||
relocation_group,
|
||||
sec_itr)) {
|
||||
if (!aot_resolve_object_relocation_group(obj_data, relocation_group,
|
||||
sec_itr)) {
|
||||
LLVMDisposeSectionIterator(sec_itr);
|
||||
return false;
|
||||
}
|
||||
|
@ -2233,8 +2242,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
|||
{
|
||||
char *err = NULL;
|
||||
AOTObjectData *obj_data;
|
||||
LLVMTargetRef target =
|
||||
LLVMGetTargetMachineTarget(comp_ctx->target_machine);
|
||||
LLVMTargetRef target = LLVMGetTargetMachineTarget(comp_ctx->target_machine);
|
||||
|
||||
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");
|
||||
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
|
||||
comp_ctx->module,
|
||||
buf, LLVMAssemblyFile,
|
||||
&err) != 0) {
|
||||
comp_ctx->module, buf, LLVMAssemblyFile,
|
||||
&err)
|
||||
!= 0) {
|
||||
if (err) {
|
||||
LLVMDisposeMessage(err);
|
||||
err = NULL;
|
||||
|
@ -2298,11 +2306,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
|||
|
||||
/* create memory buffer from object file */
|
||||
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
|
||||
ret = LLVMCreateMemoryBufferWithContentsOfFile(buf,
|
||||
&obj_data->mem_buf,
|
||||
ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf,
|
||||
&err);
|
||||
/* remove temp object file */
|
||||
snprintf(buf, sizeof(buf), "%s%s",file_name, ".o");
|
||||
snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
|
||||
unlink(buf);
|
||||
|
||||
if (ret != 0) {
|
||||
|
@ -2315,10 +2322,10 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
|||
}
|
||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||
}
|
||||
else if (LLVMTargetMachineEmitToMemoryBuffer(comp_ctx->target_machine,
|
||||
comp_ctx->module,
|
||||
LLVMObjectFile, &err,
|
||||
&obj_data->mem_buf) != 0) {
|
||||
else if (LLVMTargetMachineEmitToMemoryBuffer(
|
||||
comp_ctx->target_machine, comp_ctx->module, LLVMObjectFile,
|
||||
&err, &obj_data->mem_buf)
|
||||
!= 0) {
|
||||
if (err) {
|
||||
LLVMDisposeMessage(err);
|
||||
err = NULL;
|
||||
|
@ -2327,8 +2334,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!(obj_data->binary =
|
||||
LLVMCreateBinary(obj_data->mem_buf, NULL, &err))) {
|
||||
if (!(obj_data->binary = LLVMCreateBinary(obj_data->mem_buf, NULL, &err))) {
|
||||
if (err) {
|
||||
LLVMDisposeMessage(err);
|
||||
err = NULL;
|
||||
|
@ -2341,8 +2347,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
|||
|
||||
/* resolve target info/text/relocations/functions */
|
||||
if (!aot_resolve_target_info(comp_ctx, obj_data)
|
||||
|| !aot_resolve_text(obj_data)
|
||||
|| !aot_resolve_literal(obj_data)
|
||||
|| !aot_resolve_text(obj_data) || !aot_resolve_literal(obj_data)
|
||||
|| !aot_resolve_object_data_sections(obj_data)
|
||||
|| !aot_resolve_object_relocation_groups(obj_data)
|
||||
|| !aot_resolve_functions(comp_ctx, obj_data))
|
||||
|
@ -2355,9 +2360,8 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint8*
|
||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
||||
AOTCompData *comp_data,
|
||||
uint8 *
|
||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||
uint32 *p_aot_file_size)
|
||||
{
|
||||
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;
|
||||
|
||||
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_init_data_section(buf, buf_end, &offset, comp_ctx, comp_data, obj_data)
|
||||
|| !aot_emit_target_info_section(buf, buf_end, &offset, comp_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_func_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))
|
||||
goto fail2;
|
||||
|
||||
|
@ -2420,8 +2427,8 @@ aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
|||
|
||||
bh_print_time("Begin to emit AOT file");
|
||||
|
||||
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data,
|
||||
&aot_file_size))) {
|
||||
if (!(aot_file_buf =
|
||||
aot_emit_aot_file_buf(comp_ctx, comp_data, &aot_file_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,25 +23,25 @@ int_cond_to_llvm_op(IntCond cond, LLVMIntPredicate *op)
|
|||
case INT_LT_S:
|
||||
*op = LLVMIntSLT;
|
||||
break;
|
||||
case INT_LT_U:
|
||||
case INT_LT_U:
|
||||
*op = LLVMIntULT;
|
||||
break;
|
||||
case INT_GT_S:
|
||||
*op = LLVMIntSGT;
|
||||
break;
|
||||
case INT_GT_U:
|
||||
case INT_GT_U:
|
||||
*op = LLVMIntUGT;
|
||||
break;
|
||||
case INT_LE_S:
|
||||
*op = LLVMIntSLE;
|
||||
break;
|
||||
case INT_LE_U:
|
||||
case INT_LE_U:
|
||||
*op = LLVMIntULE;
|
||||
break;
|
||||
case INT_GE_S:
|
||||
*op = LLVMIntSGE;
|
||||
break;
|
||||
case INT_GE_U:
|
||||
case INT_GE_U:
|
||||
*op = LLVMIntUGE;
|
||||
break;
|
||||
default:
|
||||
|
@ -230,4 +230,3 @@ aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,8 @@ bool
|
|||
aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatCond cond);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_COMPARE_H_ */
|
||||
|
||||
|
|
|
@ -5,111 +5,109 @@
|
|||
|
||||
#include "aot_emit_const.h"
|
||||
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 i32_const)
|
||||
{
|
||||
LLVMValueRef value = I32_CONST((uint32)i32_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_I32(value);
|
||||
return true;
|
||||
LLVMValueRef value = I32_CONST((uint32)i32_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_I32(value);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int64 i64_const)
|
||||
{
|
||||
LLVMValueRef value = I64_CONST((uint64)i64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_I64(value);
|
||||
return true;
|
||||
LLVMValueRef value = I64_CONST((uint64)i64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_I64(value);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
float32 f32_const)
|
||||
{
|
||||
LLVMValueRef alloca, value;
|
||||
LLVMValueRef alloca, value;
|
||||
|
||||
if (!isnan(f32_const)) {
|
||||
value = F32_CONST(f32_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_F32(value);
|
||||
}
|
||||
else {
|
||||
int32 i32_const;
|
||||
memcpy(&i32_const, &f32_const, sizeof(int32));
|
||||
if (!(alloca = LLVMBuildAlloca(comp_ctx->builder,
|
||||
I32_TYPE, "i32_ptr"))) {
|
||||
aot_set_last_error("llvm build alloca failed.");
|
||||
return false;
|
||||
}
|
||||
if (!LLVMBuildStore(comp_ctx->builder,
|
||||
I32_CONST((uint32)i32_const), alloca)) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder,
|
||||
alloca, F32_PTR_TYPE, "f32_ptr"))) {
|
||||
aot_set_last_error("llvm build bitcast failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
return false;
|
||||
}
|
||||
PUSH_F32(value);
|
||||
}
|
||||
if (!isnan(f32_const)) {
|
||||
value = F32_CONST(f32_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_F32(value);
|
||||
}
|
||||
else {
|
||||
int32 i32_const;
|
||||
memcpy(&i32_const, &f32_const, sizeof(int32));
|
||||
if (!(alloca =
|
||||
LLVMBuildAlloca(comp_ctx->builder, I32_TYPE, "i32_ptr"))) {
|
||||
aot_set_last_error("llvm build alloca failed.");
|
||||
return false;
|
||||
}
|
||||
if (!LLVMBuildStore(comp_ctx->builder, I32_CONST((uint32)i32_const),
|
||||
alloca)) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, alloca, F32_PTR_TYPE,
|
||||
"f32_ptr"))) {
|
||||
aot_set_last_error("llvm build bitcast failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
return false;
|
||||
}
|
||||
PUSH_F32(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
float64 f64_const)
|
||||
{
|
||||
LLVMValueRef alloca, value;
|
||||
LLVMValueRef alloca, value;
|
||||
|
||||
if (!isnan(f64_const)) {
|
||||
value = F64_CONST(f64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_F64(value);
|
||||
}
|
||||
else {
|
||||
int64 i64_const;
|
||||
memcpy(&i64_const, &f64_const, sizeof(int64));
|
||||
if (!(alloca = LLVMBuildAlloca(comp_ctx->builder,
|
||||
I64_TYPE, "i64_ptr"))) {
|
||||
aot_set_last_error("llvm build alloca failed.");
|
||||
return false;
|
||||
}
|
||||
value = I64_CONST((uint64)i64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
if (!LLVMBuildStore(comp_ctx->builder, value, alloca)) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder,
|
||||
alloca, F64_PTR_TYPE, "f64_ptr"))) {
|
||||
aot_set_last_error("llvm build bitcast failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
return false;
|
||||
}
|
||||
PUSH_F64(value);
|
||||
}
|
||||
if (!isnan(f64_const)) {
|
||||
value = F64_CONST(f64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
PUSH_F64(value);
|
||||
}
|
||||
else {
|
||||
int64 i64_const;
|
||||
memcpy(&i64_const, &f64_const, sizeof(int64));
|
||||
if (!(alloca =
|
||||
LLVMBuildAlloca(comp_ctx->builder, I64_TYPE, "i64_ptr"))) {
|
||||
aot_set_last_error("llvm build alloca failed.");
|
||||
return false;
|
||||
}
|
||||
value = I64_CONST((uint64)i64_const);
|
||||
CHECK_LLVM_CONST(value);
|
||||
if (!LLVMBuildStore(comp_ctx->builder, value, alloca)) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(alloca = LLVMBuildBitCast(comp_ctx->builder, alloca, F64_PTR_TYPE,
|
||||
"f64_ptr"))) {
|
||||
aot_set_last_error("llvm build bitcast failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, alloca, ""))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
return false;
|
||||
}
|
||||
PUSH_F64(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,4 +33,3 @@ aot_compile_op_f64_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_CONST_H_ */
|
||||
|
||||
|
|
|
@ -15,34 +15,33 @@
|
|||
static char *block_name_prefix[] = { "block", "loop", "if" };
|
||||
static char *block_name_suffix[] = { "begin", "else", "end" };
|
||||
|
||||
/* clang-format off */
|
||||
enum {
|
||||
LABEL_BEGIN = 0,
|
||||
LABEL_ELSE,
|
||||
LABEL_END
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static void
|
||||
format_block_name(char *name, uint32 name_size,
|
||||
uint32 block_index, uint32 label_type,
|
||||
uint32 label_id)
|
||||
format_block_name(char *name, uint32 name_size, uint32 block_index,
|
||||
uint32 label_type, uint32 label_id)
|
||||
{
|
||||
if (label_type != LABEL_TYPE_FUNCTION)
|
||||
snprintf(name, name_size, "%s%d%s%s",
|
||||
block_name_prefix[label_type], block_index,
|
||||
"_", block_name_suffix[label_id]);
|
||||
snprintf(name, name_size, "%s%d%s%s", block_name_prefix[label_type],
|
||||
block_index, "_", block_name_suffix[label_id]);
|
||||
else
|
||||
snprintf(name, name_size, "%s", "func_end");
|
||||
}
|
||||
|
||||
#define CREATE_BLOCK(new_llvm_block, name) do { \
|
||||
if (!(new_llvm_block = \
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, \
|
||||
name))) { \
|
||||
aot_set_last_error("add LLVM basic block failed.");\
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CREATE_BLOCK(new_llvm_block, name) \
|
||||
do { \
|
||||
if (!(new_llvm_block = LLVMAppendBasicBlockInContext( \
|
||||
comp_ctx->context, func_ctx->func, name))) { \
|
||||
aot_set_last_error("add LLVM basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#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) \
|
||||
LLVMMoveBasicBlockBefore(llvm_block, llvm_block_before)
|
||||
|
||||
#define BUILD_BR(llvm_block) do { \
|
||||
if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
|
||||
aot_set_last_error("llvm build br failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_BR(llvm_block) \
|
||||
do { \
|
||||
if (!LLVMBuildBr(comp_ctx->builder, llvm_block)) { \
|
||||
aot_set_last_error("llvm build br failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_COND_BR(value_if, block_then, block_else) do {\
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, value_if, \
|
||||
block_then, block_else)) { \
|
||||
aot_set_last_error("llvm build cond br failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_COND_BR(value_if, block_then, block_else) \
|
||||
do { \
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, value_if, block_then, \
|
||||
block_else)) { \
|
||||
aot_set_last_error("llvm build cond br failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_BUILDER_POS(llvm_block) \
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, llvm_block)
|
||||
|
||||
#define CREATE_RESULT_VALUE_PHIS(block) do { \
|
||||
if (block->result_count && !block->result_phis) { \
|
||||
uint32 i; \
|
||||
uint64 size; \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
/* Allocate memory */ \
|
||||
size = sizeof(LLVMValueRef) * (uint64)block->result_count; \
|
||||
if (size >= UINT32_MAX \
|
||||
|| !(block->result_phis = \
|
||||
wasm_runtime_malloc((uint32)size))) { \
|
||||
aot_set_last_error("allocate memory failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
SET_BUILDER_POS(block->llvm_end_block); \
|
||||
for (i = 0; i < block->result_count; i++) { \
|
||||
if (!(block->result_phis[i] = \
|
||||
LLVMBuildPhi(comp_ctx->builder, \
|
||||
TO_LLVM_TYPE(block->result_types[i]), \
|
||||
"phi"))) { \
|
||||
aot_set_last_error("llvm build phi failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
SET_BUILDER_POS(block_curr); \
|
||||
} \
|
||||
} while (0)
|
||||
#define CREATE_RESULT_VALUE_PHIS(block) \
|
||||
do { \
|
||||
if (block->result_count && !block->result_phis) { \
|
||||
uint32 i; \
|
||||
uint64 size; \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
/* Allocate memory */ \
|
||||
size = sizeof(LLVMValueRef) * (uint64)block->result_count; \
|
||||
if (size >= UINT32_MAX \
|
||||
|| !(block->result_phis = \
|
||||
wasm_runtime_malloc((uint32)size))) { \
|
||||
aot_set_last_error("allocate memory failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
SET_BUILDER_POS(block->llvm_end_block); \
|
||||
for (i = 0; i < block->result_count; i++) { \
|
||||
if (!(block->result_phis[i] = LLVMBuildPhi( \
|
||||
comp_ctx->builder, \
|
||||
TO_LLVM_TYPE(block->result_types[i]), "phi"))) { \
|
||||
aot_set_last_error("llvm build phi failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
SET_BUILDER_POS(block_curr); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ADD_TO_RESULT_PHIS(block, value, idx) do { \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
|
||||
LLVMTypeRef value_ty = LLVMTypeOf(value); \
|
||||
bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
|
||||
bh_assert(LLVMGetTypeContext(phi_ty) \
|
||||
== LLVMGetTypeContext(value_ty)); \
|
||||
LLVMAddIncoming(block->result_phis[idx], &value, &block_curr, 1); \
|
||||
(void)phi_ty; \
|
||||
(void)value_ty; \
|
||||
} while (0)
|
||||
#define ADD_TO_RESULT_PHIS(block, value, idx) \
|
||||
do { \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
LLVMTypeRef phi_ty = LLVMTypeOf(block->result_phis[idx]); \
|
||||
LLVMTypeRef value_ty = LLVMTypeOf(value); \
|
||||
bh_assert(LLVMGetTypeKind(phi_ty) == LLVMGetTypeKind(value_ty)); \
|
||||
bh_assert(LLVMGetTypeContext(phi_ty) == LLVMGetTypeContext(value_ty)); \
|
||||
LLVMAddIncoming(block->result_phis[idx], &value, &block_curr, 1); \
|
||||
(void)phi_ty; \
|
||||
(void)value_ty; \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_ICMP(op, left, right, res, name) do { \
|
||||
if (!(res = LLVMBuildICmp(comp_ctx->builder, op, \
|
||||
left, right, name))) { \
|
||||
aot_set_last_error("llvm build icmp failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_ICMP(op, left, right, res, name) \
|
||||
do { \
|
||||
if (!(res = \
|
||||
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
|
||||
aot_set_last_error("llvm build icmp failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ADD_TO_PARAM_PHIS(block, value, idx) do { \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
LLVMAddIncoming(block->param_phis[idx], \
|
||||
&value, &block_curr, 1); \
|
||||
} while (0)
|
||||
#define ADD_TO_PARAM_PHIS(block, value, idx) \
|
||||
do { \
|
||||
LLVMBasicBlockRef block_curr = CURR_BLOCK(); \
|
||||
LLVMAddIncoming(block->param_phis[idx], &value, &block_curr, 1); \
|
||||
} while (0)
|
||||
|
||||
static LLVMBasicBlockRef
|
||||
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;
|
||||
}
|
||||
|
||||
static AOTBlock*
|
||||
static AOTBlock *
|
||||
get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
|
||||
{
|
||||
uint32 i = br_depth;
|
||||
|
@ -153,8 +155,7 @@ get_target_block(AOTFuncContext *func_ctx, uint32 br_depth)
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_next_reachable_block(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip)
|
||||
{
|
||||
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
|
||||
return_location = dwarf_gen_location(
|
||||
comp_ctx, func_ctx,
|
||||
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code
|
||||
);
|
||||
comp_ctx, func_ctx,
|
||||
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
|
||||
#endif
|
||||
if (block->label_type == LABEL_TYPE_IF
|
||||
&& block->llvm_else_block
|
||||
if (block->label_type == LABEL_TYPE_IF && block->llvm_else_block
|
||||
&& *p_frame_ip <= block->wasm_code_else) {
|
||||
/* Clear value stack and start to translate else branch */
|
||||
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);
|
||||
|
||||
if (block->label_type == LABEL_TYPE_IF) {
|
||||
if (block->llvm_else_block
|
||||
&& !block->skip_wasm_code_else
|
||||
if (block->llvm_else_block && !block->skip_wasm_code_else
|
||||
&& *p_frame_ip <= block->wasm_code_else) {
|
||||
/* Clear value stack and start to translate else branch */
|
||||
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 */
|
||||
if (i != 0) {
|
||||
uint32 param_index = func_type->param_count + i;
|
||||
if (!LLVMBuildStore(comp_ctx->builder,
|
||||
block->result_phis[i],
|
||||
LLVMGetParam(func_ctx->func, param_index))) {
|
||||
if (!LLVMBuildStore(
|
||||
comp_ctx->builder, block->result_phis[i],
|
||||
LLVMGetParam(func_ctx->func, param_index))) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -250,7 +248,7 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
|
|||
if (block->result_count) {
|
||||
/* Return the first return value */
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -293,8 +291,7 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (block->label_type == LABEL_TYPE_IF
|
||||
&& !block->skip_wasm_code_else
|
||||
if (block->label_type == LABEL_TYPE_IF && !block->skip_wasm_code_else
|
||||
&& !(block->else_param_phis = wasm_runtime_malloc((uint32)size))) {
|
||||
wasm_runtime_free(block->param_phis);
|
||||
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++) {
|
||||
SET_BUILDER_POS(block->llvm_entry_block);
|
||||
snprintf(name, sizeof(name), "%s%d_phi%d",
|
||||
block_name_prefix[block->label_type],
|
||||
block->block_index, i);
|
||||
if (!(block->param_phis[i] =
|
||||
LLVMBuildPhi(comp_ctx->builder,
|
||||
TO_LLVM_TYPE(block->param_types[i]),
|
||||
name))) {
|
||||
block_name_prefix[block->label_type], block->block_index,
|
||||
i);
|
||||
if (!(block->param_phis[i] = LLVMBuildPhi(
|
||||
comp_ctx->builder, TO_LLVM_TYPE(block->param_types[i]),
|
||||
name))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (block->label_type == LABEL_TYPE_IF
|
||||
&& !block->skip_wasm_code_else
|
||||
&& block->llvm_else_block) {
|
||||
&& !block->skip_wasm_code_else && block->llvm_else_block) {
|
||||
/* Build else param phis */
|
||||
SET_BUILDER_POS(block->llvm_else_block);
|
||||
snprintf(name, sizeof(name), "else%d_phi%d",
|
||||
block->block_index, i);
|
||||
if (!(block->else_param_phis[i] =
|
||||
LLVMBuildPhi(comp_ctx->builder,
|
||||
TO_LLVM_TYPE(block->param_types[i]),
|
||||
name))) {
|
||||
snprintf(name, sizeof(name), "else%d_phi%d", block->block_index,
|
||||
i);
|
||||
if (!(block->else_param_phis[i] = LLVMBuildPhi(
|
||||
comp_ctx->builder,
|
||||
TO_LLVM_TYPE(block->param_types[i]), name))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -345,8 +339,8 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
|||
&& !block->skip_wasm_code_else) {
|
||||
if (block->llvm_else_block) {
|
||||
/* has else branch, add to else param phis */
|
||||
LLVMAddIncoming(block->else_param_phis[param_index],
|
||||
&value, &block_curr, 1);
|
||||
LLVMAddIncoming(block->else_param_phis[param_index], &value,
|
||||
&block_curr, 1);
|
||||
}
|
||||
else {
|
||||
/* no else branch, add to result phis */
|
||||
|
@ -381,8 +375,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip, uint8 *frame_ip_end,
|
||||
uint32 label_type, uint32 param_count, uint8 *param_types,
|
||||
uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
|
||||
uint32 param_count, uint8 *param_types,
|
||||
uint32 result_count, uint8 *result_types)
|
||||
{
|
||||
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));
|
||||
|
||||
/* Get block info */
|
||||
if (!(wasm_loader_find_block_addr(NULL, (BlockAddr*)block_addr_cache,
|
||||
*p_frame_ip, frame_ip_end, (uint8)label_type,
|
||||
&else_addr, &end_addr))) {
|
||||
if (!(wasm_loader_find_block_addr(
|
||||
NULL, (BlockAddr *)block_addr_cache, *p_frame_ip, frame_ip_end,
|
||||
(uint8)label_type, &else_addr, &end_addr))) {
|
||||
aot_set_last_error("find block end addr failed.");
|
||||
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];
|
||||
func_ctx->block_stack.block_index[label_type]++;
|
||||
|
||||
if (label_type == LABEL_TYPE_BLOCK
|
||||
|| label_type == LABEL_TYPE_LOOP) {
|
||||
if (label_type == LABEL_TYPE_BLOCK || label_type == LABEL_TYPE_LOOP) {
|
||||
/* Create block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_BEGIN);
|
||||
format_block_name(name, sizeof(name), block->block_index, label_type,
|
||||
LABEL_BEGIN);
|
||||
CREATE_BLOCK(block->llvm_entry_block, name);
|
||||
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
|
||||
/* Jump to the entry block */
|
||||
|
@ -471,23 +464,24 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!LLVMIsConstant(value)) {
|
||||
/* Compare value is not constant, create condition br IR */
|
||||
/* Create entry block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_BEGIN);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
label_type, LABEL_BEGIN);
|
||||
CREATE_BLOCK(block->llvm_entry_block, name);
|
||||
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
|
||||
|
||||
/* Create end block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_END);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
label_type, LABEL_END);
|
||||
CREATE_BLOCK(block->llvm_end_block, name);
|
||||
MOVE_BLOCK_AFTER(block->llvm_end_block, block->llvm_entry_block);
|
||||
|
||||
if (else_addr) {
|
||||
/* Create else block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_ELSE);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
label_type, LABEL_ELSE);
|
||||
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 */
|
||||
BUILD_COND_BR(value, block->llvm_entry_block,
|
||||
block->llvm_else_block);
|
||||
|
@ -498,7 +492,8 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
block->llvm_end_block);
|
||||
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;
|
||||
/* Start to translate if branch of BLOCK if */
|
||||
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->skip_wasm_code_else = true;
|
||||
/* Create entry block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_BEGIN);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
label_type, LABEL_BEGIN);
|
||||
CREATE_BLOCK(block->llvm_entry_block, name);
|
||||
MOVE_BLOCK_AFTER_CURR(block->llvm_entry_block);
|
||||
/* Jump to the 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;
|
||||
/* Start to translate the if branch */
|
||||
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 */
|
||||
if (else_addr) {
|
||||
/* Create else block */
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, label_type, LABEL_ELSE);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
label_type, LABEL_ELSE);
|
||||
CREATE_BLOCK(block->llvm_else_block, name);
|
||||
MOVE_BLOCK_AFTER_CURR(block->llvm_else_block);
|
||||
/* Jump to the 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;
|
||||
/* Start to translate the else branch */
|
||||
SET_BUILDER_POS(block->llvm_else_block);
|
||||
|
@ -571,16 +568,15 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
if (block->label_type != LABEL_TYPE_IF
|
||||
|| (!block->skip_wasm_code_else
|
||||
&& !block->llvm_else_block)) {
|
||||
|| (!block->skip_wasm_code_else && !block->llvm_else_block)) {
|
||||
aot_set_last_error("Invalid WASM block type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create end block if needed */
|
||||
if (!block->llvm_end_block) {
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, block->label_type, LABEL_END);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
block->label_type, LABEL_END);
|
||||
CREATE_BLOCK(block->llvm_end_block, name);
|
||||
if (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 */
|
||||
BUILD_BR(block->llvm_end_block);
|
||||
|
||||
if (!block->skip_wasm_code_else
|
||||
&& block->llvm_else_block) {
|
||||
if (!block->skip_wasm_code_else && block->llvm_else_block) {
|
||||
/* Clear value stack, recover param values
|
||||
* and start to translate else branch.
|
||||
*/
|
||||
|
@ -639,8 +634,8 @@ aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Create the end block */
|
||||
if (!block->llvm_end_block) {
|
||||
format_block_name(name, sizeof(name),
|
||||
block->block_index, block->label_type, LABEL_END);
|
||||
format_block_name(name, sizeof(name), block->block_index,
|
||||
block->label_type, LABEL_END);
|
||||
CREATE_BLOCK(block->llvm_end_block, name);
|
||||
if ((next_llvm_end_block = find_next_llvm_end_block(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;
|
||||
|
||||
if (!(terminate_addr =
|
||||
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
|
||||
&offset, 1, "terminate_addr"))) {
|
||||
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
|
||||
&offset, 1, "terminate_addr"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
if (!(terminate_addr =
|
||||
LLVMBuildBitCast(comp_ctx->builder,
|
||||
terminate_addr,
|
||||
INT32_PTR_TYPE, "terminate_addr_ptr"))) {
|
||||
LLVMBuildBitCast(comp_ctx->builder, terminate_addr,
|
||||
INT32_PTR_TYPE, "terminate_addr_ptr"))) {
|
||||
aot_set_last_error("llvm build bit cast failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(terminate_flags =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
terminate_addr, "terminate_flags"))) {
|
||||
if (!(terminate_flags = LLVMBuildLoad(comp_ctx->builder, terminate_addr,
|
||||
"terminate_flags"))) {
|
||||
aot_set_last_error("llvm build bit cast failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -716,9 +709,8 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
CREATE_BLOCK(terminate_block, "terminate");
|
||||
MOVE_BLOCK_AFTER_CURR(terminate_block);
|
||||
|
||||
if (!(flag =
|
||||
LLVMBuildAnd(comp_ctx->builder, terminate_flags,
|
||||
I32_ONE, "termination_flag"))) {
|
||||
if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE,
|
||||
"termination_flag"))) {
|
||||
aot_set_last_error("llvm build AND failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -777,9 +769,8 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Dest block is Block/If/Function block */
|
||||
/* Create the end block */
|
||||
if (!block_dst->llvm_end_block) {
|
||||
format_block_name(name, sizeof(name),
|
||||
block_dst->block_index, block_dst->label_type,
|
||||
LABEL_END);
|
||||
format_block_name(name, sizeof(name), block_dst->block_index,
|
||||
block_dst->label_type, LABEL_END);
|
||||
CREATE_BLOCK(block_dst->llvm_end_block, name);
|
||||
if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
|
||||
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 */
|
||||
/* Create the end block */
|
||||
if (!block_dst->llvm_end_block) {
|
||||
format_block_name(name, sizeof(name),
|
||||
block_dst->block_index, block_dst->label_type,
|
||||
LABEL_END);
|
||||
format_block_name(name, sizeof(name), block_dst->block_index,
|
||||
block_dst->label_type, LABEL_END);
|
||||
CREATE_BLOCK(block_dst->llvm_end_block, name);
|
||||
if ((next_llvm_end_block = find_next_llvm_end_block(block_dst)))
|
||||
MOVE_BLOCK_BEFORE(block_dst->llvm_end_block,
|
||||
|
@ -941,8 +931,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 *br_depths, uint32 br_count,
|
||||
uint8 **p_frame_ip)
|
||||
uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip)
|
||||
{
|
||||
uint32 i, j;
|
||||
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) {
|
||||
format_block_name(name, sizeof(name),
|
||||
target_block->block_index,
|
||||
target_block->label_type,
|
||||
LABEL_END);
|
||||
target_block->label_type, LABEL_END);
|
||||
CREATE_BLOCK(target_block->llvm_end_block, name);
|
||||
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,
|
||||
next_llvm_end_block);
|
||||
}
|
||||
/* Handle result values */
|
||||
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
|
||||
|| !(values = wasm_runtime_malloc((uint32)size))) {
|
||||
aot_set_last_error("allocate memory failed.");
|
||||
|
@ -1024,7 +1013,8 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
else {
|
||||
/* Handle Loop parameters */
|
||||
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
|
||||
|| !(values = wasm_runtime_malloc((uint32)size))) {
|
||||
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)
|
||||
return false;
|
||||
target_llvm_block = target_block->label_type != LABEL_TYPE_LOOP
|
||||
? target_block->llvm_end_block
|
||||
: target_block->llvm_entry_block;
|
||||
? target_block->llvm_end_block
|
||||
: target_block->llvm_entry_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
|
||||
return_location = dwarf_gen_location(
|
||||
comp_ctx, func_ctx,
|
||||
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code
|
||||
);
|
||||
comp_ctx, func_ctx,
|
||||
(*p_frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
|
||||
#endif
|
||||
if (block_func->result_count) {
|
||||
/* 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;
|
||||
POP(value, block_func->result_types[result_index]);
|
||||
param_index = func_type->param_count + result_index;
|
||||
if (!LLVMBuildStore(comp_ctx->builder,
|
||||
value,
|
||||
if (!LLVMBuildStore(comp_ctx->builder, value,
|
||||
LLVMGetParam(func_ctx->func, param_index))) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
goto fail;
|
||||
|
@ -1144,12 +1132,11 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_unreachable(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip)
|
||||
{
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE,
|
||||
false, NULL, NULL))
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNREACHABLE, false, NULL,
|
||||
NULL))
|
||||
return false;
|
||||
|
||||
return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
|
||||
|
@ -1157,8 +1144,7 @@ aot_compile_op_unreachable(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip)
|
||||
AOTFuncContext *func_ctx, uint8 **p_frame_ip)
|
||||
{
|
||||
return handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip, uint8 *frame_ip_end,
|
||||
uint32 label_type, uint32 param_count, uint8 *param_types,
|
||||
uint8 **p_frame_ip, uint8 *frame_ip_end, uint32 label_type,
|
||||
uint32 param_count, uint8 *param_types,
|
||||
uint32 result_count, uint8 *result_types);
|
||||
|
||||
bool
|
||||
|
@ -36,22 +36,19 @@ aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 *br_depths, uint32 br_count,
|
||||
uint8 **p_frame_ip);
|
||||
uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_unreachable(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_unreachable(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 **p_frame_ip);
|
||||
AOTFuncContext *func_ctx, uint8 **p_frame_ip);
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
bool
|
||||
|
@ -63,4 +60,3 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_CONTROL_H_ */
|
||||
|
||||
|
|
|
@ -11,24 +11,24 @@
|
|||
|
||||
static bool
|
||||
trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef operand, LLVMTypeRef src_type, LLVMTypeRef dest_type,
|
||||
LLVMValueRef min_value, LLVMValueRef max_value,
|
||||
char *name, bool sign)
|
||||
LLVMValueRef operand, LLVMTypeRef src_type,
|
||||
LLVMTypeRef dest_type, LLVMValueRef min_value,
|
||||
LLVMValueRef max_value, char *name, bool sign)
|
||||
{
|
||||
LLVMBasicBlockRef check_nan_succ, check_overflow_succ;
|
||||
LLVMValueRef is_less, is_greater, res;
|
||||
|
||||
if (comp_ctx->disable_llvm_intrinsics
|
||||
&& 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];
|
||||
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_UNO, true);
|
||||
param_types[0] = I32_TYPE;
|
||||
param_types[1] = src_type;
|
||||
param_types[2] = src_type;
|
||||
res = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, operand);
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, operand);
|
||||
if (!res) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -44,10 +44,8 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!(check_nan_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_nan_succ"))) {
|
||||
if (!(check_nan_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_nan_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -55,26 +53,27 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(check_nan_succ,
|
||||
LLVMGetInsertBlock(comp_ctx->builder));
|
||||
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||
true, res, check_nan_succ)))
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_INVALID_CONVERSION_TO_INTEGER, true, res,
|
||||
check_nan_succ)))
|
||||
goto fail;
|
||||
|
||||
if (comp_ctx->disable_llvm_intrinsics
|
||||
&& 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];
|
||||
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_LE, true);
|
||||
param_types[0] = I32_TYPE;
|
||||
param_types[1] = src_type;
|
||||
param_types[2] = src_type;
|
||||
is_less = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, min_value);
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, min_value);
|
||||
if (!is_less) {
|
||||
goto fail;
|
||||
}
|
||||
is_less =
|
||||
LLVMBuildIntCast(comp_ctx->builder, is_less, INT1_TYPE, "bit_cast");
|
||||
LLVMBuildIntCast(comp_ctx->builder, is_less, INT1_TYPE, "bit_cast");
|
||||
}
|
||||
else {
|
||||
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
|
||||
&& 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];
|
||||
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_GE, true);
|
||||
param_types[0] = I32_TYPE;
|
||||
param_types[1] = src_type;
|
||||
param_types[2] = src_type;
|
||||
is_greater = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, max_value);
|
||||
comp_ctx, func_ctx, src_type == F32_TYPE ? "f32_cmp" : "f64_cmp",
|
||||
I32_TYPE, param_types, 3, opcond, operand, max_value);
|
||||
if (!is_greater) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -113,16 +112,15 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
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.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check if float value out of range */
|
||||
if (!(check_overflow_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_overflow_succ"))) {
|
||||
if (!(check_overflow_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_overflow_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -130,8 +128,8 @@ trunc_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(check_overflow_succ,
|
||||
LLVMGetInsertBlock(comp_ctx->builder));
|
||||
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW,
|
||||
true, res, check_overflow_succ)))
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_INTEGER_OVERFLOW, true,
|
||||
res, check_overflow_succ)))
|
||||
goto fail;
|
||||
|
||||
if (comp_ctx->disable_llvm_intrinsics
|
||||
|
@ -162,22 +160,22 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#define ADD_BASIC_BLOCK(block, name) do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, \
|
||||
name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
\
|
||||
LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \
|
||||
} while (0)
|
||||
#define ADD_BASIC_BLOCK(block, name) \
|
||||
do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
\
|
||||
LLVMMoveBasicBlockAfter(block, LLVMGetInsertBlock(comp_ctx->builder)); \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef operand, LLVMTypeRef src_type, LLVMTypeRef dest_type,
|
||||
LLVMValueRef min_value, LLVMValueRef max_value,
|
||||
char *name, bool sign)
|
||||
LLVMValueRef operand, LLVMTypeRef src_type,
|
||||
LLVMTypeRef dest_type, LLVMValueRef min_value,
|
||||
LLVMValueRef max_value, char *name, bool sign)
|
||||
{
|
||||
LLVMBasicBlockRef check_nan_succ, check_less_succ, check_greater_succ;
|
||||
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 vmin, vmax;
|
||||
|
||||
if (!(res = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO,
|
||||
operand, operand, "fcmp_is_nan"))) {
|
||||
if (!(res = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, operand, operand,
|
||||
"fcmp_is_nan"))) {
|
||||
aot_set_last_error("llvm build fcmp failed.");
|
||||
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(res_block, "res_block");
|
||||
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, res,
|
||||
is_nan_block, check_nan_succ)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, res, is_nan_block,
|
||||
check_nan_succ)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, is_less,
|
||||
is_less_block, check_less_succ)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, is_less, is_less_block,
|
||||
check_less_succ)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, is_greater,
|
||||
is_greater_block, check_greater_succ)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, is_greater, is_greater_block,
|
||||
check_greater_succ)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -281,8 +279,7 @@ trunc_sat_float_to_int(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Start to translate res_block */
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, res_block);
|
||||
/* Create result phi */
|
||||
if (!(phi = LLVMBuildPhi(comp_ctx->builder,
|
||||
dest_type,
|
||||
if (!(phi = LLVMBuildPhi(comp_ctx->builder, dest_type,
|
||||
"trunc_sat_result_phi"))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
return false;
|
||||
|
@ -330,7 +327,8 @@ aot_compile_op_i32_wrap_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -360,14 +358,13 @@ aot_compile_op_i32_trunc_f32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!saturating)
|
||||
return trunc_float_to_int(comp_ctx, func_ctx, value,
|
||||
F32_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_f32_s" : "i32_trunc_f32_u", sign);
|
||||
return trunc_float_to_int(
|
||||
comp_ctx, func_ctx, value, F32_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_f32_s" : "i32_trunc_f32_u", sign);
|
||||
else
|
||||
return trunc_sat_float_to_int(comp_ctx, func_ctx, value,
|
||||
F32_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_sat_f32_s" :
|
||||
"i32_trunc_sat_f32_u", sign);
|
||||
return trunc_sat_float_to_int(
|
||||
comp_ctx, func_ctx, value, F32_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_sat_f32_s" : "i32_trunc_sat_f32_u", sign);
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
@ -391,30 +388,31 @@ aot_compile_op_i32_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!saturating)
|
||||
return trunc_float_to_int(comp_ctx, func_ctx, value,
|
||||
F64_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_f64_s" : "i32_trunc_f64_u", sign);
|
||||
return trunc_float_to_int(
|
||||
comp_ctx, func_ctx, value, F64_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_f64_s" : "i32_trunc_f64_u", sign);
|
||||
else
|
||||
return trunc_sat_float_to_int(comp_ctx, func_ctx, value,
|
||||
F64_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_sat_f64_s" :
|
||||
"i32_trunc_sat_f64_u", sign);
|
||||
return trunc_sat_float_to_int(
|
||||
comp_ctx, func_ctx, value, F64_TYPE, I32_TYPE, min_value, max_value,
|
||||
sign ? "i32_trunc_sat_f64_s" : "i32_trunc_sat_f64_u", sign);
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign)
|
||||
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign)
|
||||
{
|
||||
LLVMValueRef value, res;
|
||||
|
||||
POP_I32(value);
|
||||
|
||||
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
|
||||
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) {
|
||||
aot_set_last_error("llvm build conversion failed.");
|
||||
return false;
|
||||
|
@ -427,24 +425,24 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int8 bitwidth)
|
||||
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, int8 bitwidth)
|
||||
{
|
||||
LLVMValueRef value, res, cast_value = NULL;
|
||||
|
||||
POP_I64(value);
|
||||
|
||||
if (bitwidth == 8) {
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value,
|
||||
INT8_TYPE, true, "i8_intcast_i64");
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT8_TYPE,
|
||||
true, "i8_intcast_i64");
|
||||
}
|
||||
else if (bitwidth == 16) {
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value,
|
||||
INT16_TYPE, true, "i16_intcast_i64");
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT16_TYPE,
|
||||
true, "i16_intcast_i64");
|
||||
}
|
||||
else if (bitwidth == 32) {
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value,
|
||||
I32_TYPE, true, "i32_intcast_i64");
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, I32_TYPE, true,
|
||||
"i32_intcast_i64");
|
||||
}
|
||||
|
||||
if (!cast_value) {
|
||||
|
@ -452,7 +450,8 @@ aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx
|
|||
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) {
|
||||
aot_set_last_error("llvm build conversion failed.");
|
||||
|
@ -466,20 +465,20 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int8 bitwidth)
|
||||
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, int8 bitwidth)
|
||||
{
|
||||
LLVMValueRef value, res, cast_value = NULL;
|
||||
|
||||
POP_I32(value);
|
||||
|
||||
if (bitwidth == 8) {
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value,
|
||||
INT8_TYPE, true, "i8_intcast_i32");
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT8_TYPE,
|
||||
true, "i8_intcast_i32");
|
||||
}
|
||||
else if (bitwidth == 16) {
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value,
|
||||
INT16_TYPE, true, "i16_intcast_i32");
|
||||
cast_value = LLVMBuildIntCast2(comp_ctx->builder, value, INT16_TYPE,
|
||||
true, "i16_intcast_i32");
|
||||
}
|
||||
|
||||
if (!cast_value) {
|
||||
|
@ -487,7 +486,8 @@ aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx
|
|||
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) {
|
||||
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)
|
||||
return trunc_float_to_int(comp_ctx, func_ctx, value,
|
||||
F32_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_f32_s" : "i64_trunc_f32_u", sign);
|
||||
return trunc_float_to_int(
|
||||
comp_ctx, func_ctx, value, F32_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_f32_s" : "i64_trunc_f32_u", sign);
|
||||
else
|
||||
return trunc_sat_float_to_int(comp_ctx, func_ctx, value,
|
||||
F32_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_sat_f32_s" :
|
||||
"i64_trunc_sat_f32_u", sign);
|
||||
return trunc_sat_float_to_int(
|
||||
comp_ctx, func_ctx, value, F32_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_sat_f32_s" : "i64_trunc_sat_f32_u", sign);
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
@ -550,22 +549,21 @@ aot_compile_op_i64_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!saturating)
|
||||
return trunc_float_to_int(comp_ctx, func_ctx, value,
|
||||
F64_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_f64_s" : "i64_trunc_f64_u", sign);
|
||||
return trunc_float_to_int(
|
||||
comp_ctx, func_ctx, value, F64_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_f64_s" : "i64_trunc_f64_u", sign);
|
||||
else
|
||||
return trunc_sat_float_to_int(comp_ctx, func_ctx, value,
|
||||
F64_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_sat_f64_s" :
|
||||
"i64_trunc_sat_f64_u", sign);
|
||||
return trunc_sat_float_to_int(
|
||||
comp_ctx, func_ctx, value, F64_TYPE, I64_TYPE, min_value, max_value,
|
||||
sign ? "i64_trunc_sat_f64_s" : "i64_trunc_sat_f64_u", sign);
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign)
|
||||
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign)
|
||||
{
|
||||
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
|
||||
&& 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];
|
||||
param_types[0] = I32_TYPE;
|
||||
res = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, sign ? "f32_convert_i32_s" : "f32_convert_i32_u",
|
||||
F32_TYPE, param_types, 1, value);
|
||||
res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
|
||||
sign ? "f32_convert_i32_s"
|
||||
: "f32_convert_i32_u",
|
||||
F32_TYPE, param_types, 1, value);
|
||||
}
|
||||
else {
|
||||
if (sign)
|
||||
|
@ -600,8 +599,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign)
|
||||
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign)
|
||||
{
|
||||
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
|
||||
&& 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];
|
||||
param_types[0] = I64_TYPE;
|
||||
res = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, sign ? "f32_convert_i64_s" : "f32_convert_i64_u",
|
||||
F32_TYPE, param_types, 1, value);
|
||||
res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
|
||||
sign ? "f32_convert_i64_s"
|
||||
: "f32_convert_i64_u",
|
||||
F32_TYPE, param_types, 1, value);
|
||||
}
|
||||
else {
|
||||
if (sign)
|
||||
|
@ -637,7 +637,8 @@ fail:
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -667,8 +668,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign)
|
||||
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign)
|
||||
{
|
||||
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
|
||||
&& 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];
|
||||
param_types[0] = I32_TYPE;
|
||||
|
||||
res = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, sign ? "f64_convert_i32_s" : "f64_convert_i32_u",
|
||||
F64_TYPE, param_types, 1, value);
|
||||
res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
|
||||
sign ? "f64_convert_i32_s"
|
||||
: "f64_convert_i32_u",
|
||||
F64_TYPE, param_types, 1, value);
|
||||
}
|
||||
else {
|
||||
if (sign)
|
||||
|
@ -705,8 +707,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign)
|
||||
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign)
|
||||
{
|
||||
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
|
||||
&& 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];
|
||||
param_types[0] = I64_TYPE;
|
||||
|
||||
res = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, sign ? "f64_convert_i64_s" : "f64_convert_i64_u",
|
||||
F64_TYPE, param_types, 1, value);
|
||||
res = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
|
||||
sign ? "f64_convert_i64_s"
|
||||
: "f64_convert_i64_u",
|
||||
F64_TYPE, param_types, 1, value);
|
||||
}
|
||||
else {
|
||||
if (sign)
|
||||
|
@ -743,7 +746,8 @@ fail:
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -781,8 +785,8 @@ aot_compile_op_i64_reinterpret_f64(AOTCompContext *comp_ctx,
|
|||
{
|
||||
LLVMValueRef value;
|
||||
POP_F64(value);
|
||||
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value,
|
||||
I64_TYPE, "i64"))) {
|
||||
if (!(value =
|
||||
LLVMBuildBitCast(comp_ctx->builder, value, I64_TYPE, "i64"))) {
|
||||
aot_set_last_error("llvm build fp to si failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -792,15 +796,14 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_reinterpret_f32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef value;
|
||||
POP_F32(value);
|
||||
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value,
|
||||
I32_TYPE, "i32"))) {
|
||||
if (!(value =
|
||||
LLVMBuildBitCast(comp_ctx->builder, value, I32_TYPE, "i32"))) {
|
||||
aot_set_last_error("llvm build fp to si failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -816,8 +819,8 @@ aot_compile_op_f64_reinterpret_i64(AOTCompContext *comp_ctx,
|
|||
{
|
||||
LLVMValueRef value;
|
||||
POP_I64(value);
|
||||
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value,
|
||||
F64_TYPE, "f64"))) {
|
||||
if (!(value =
|
||||
LLVMBuildBitCast(comp_ctx->builder, value, F64_TYPE, "f64"))) {
|
||||
aot_set_last_error("llvm build si to fp failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -833,8 +836,8 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
|
|||
{
|
||||
LLVMValueRef value;
|
||||
POP_I32(value);
|
||||
if (!(value = LLVMBuildBitCast(comp_ctx->builder, value,
|
||||
F32_TYPE, "f32"))) {
|
||||
if (!(value =
|
||||
LLVMBuildBitCast(comp_ctx->builder, value, F32_TYPE, "f32"))) {
|
||||
aot_set_last_error("llvm build si to fp failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -843,4 +846,3 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,16 @@ aot_compile_op_i32_trunc_f64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
bool sign, bool saturating);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign);
|
||||
aot_compile_op_i64_extend_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int8 bitwidth);
|
||||
aot_compile_op_i64_extend_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, int8 bitwidth);
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int8 bitwidth);
|
||||
aot_compile_op_i32_extend_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, int8 bitwidth);
|
||||
|
||||
bool
|
||||
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
|
||||
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign);
|
||||
aot_compile_op_f32_convert_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign);
|
||||
|
||||
bool
|
||||
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign);
|
||||
aot_compile_op_f32_convert_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign);
|
||||
|
||||
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
|
||||
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign);
|
||||
aot_compile_op_f64_convert_i32(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign);
|
||||
|
||||
bool
|
||||
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool sign);
|
||||
aot_compile_op_f64_convert_i64(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, bool sign);
|
||||
|
||||
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
|
||||
aot_compile_op_i64_reinterpret_f64(AOTCompContext *comp_ctx,
|
||||
|
@ -86,4 +88,3 @@ aot_compile_op_f32_reinterpret_i32(AOTCompContext *comp_ctx,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_CONVERSION_H_ */
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
bool
|
||||
aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 exception_id,
|
||||
bool is_cond_br,
|
||||
LLVMValueRef cond_br_if,
|
||||
int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
|
||||
LLVMBasicBlockRef cond_br_else_block)
|
||||
{
|
||||
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 */
|
||||
if (!func_ctx->got_exception_block) {
|
||||
if (!(func_ctx->got_exception_block =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"got_exception"))) {
|
||||
if (!(func_ctx->got_exception_block = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "got_exception"))) {
|
||||
aot_set_last_error("add LLVM basic block failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -37,7 +33,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Create exection id phi */
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -48,8 +44,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
ret_type = VOID_TYPE;
|
||||
|
||||
/* Create function type */
|
||||
if (!(func_type = LLVMFunctionType(ret_type, param_types,
|
||||
2, false))) {
|
||||
if (!(func_type = LLVMFunctionType(ret_type, param_types, 2, false))) {
|
||||
aot_set_last_error("create LLVM function type failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -62,7 +57,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
/* Create LLVM function with const function pointer */
|
||||
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))) {
|
||||
aot_set_last_error("create LLVM value failed.");
|
||||
return false;
|
||||
|
@ -76,13 +71,13 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
if (!(func =
|
||||
aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
|
||||
func_ptr_type, func_index))) {
|
||||
aot_get_func_from_table(comp_ctx, func_ctx->native_symbol,
|
||||
func_ptr_type, func_index))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -101,8 +96,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Call the aot_set_exception_with_id() function */
|
||||
param_values[0] = func_ctx->aot_inst;
|
||||
param_values[1] = func_ctx->exception_id_phi;
|
||||
if (!LLVMBuildCall(comp_ctx->builder, func, param_values,
|
||||
2, "")) {
|
||||
if (!LLVMBuildCall(comp_ctx->builder, func, param_values, 2, "")) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -130,7 +124,8 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
else {
|
||||
/* Create condition br */
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -142,4 +137,3 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,7 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 exception_id,
|
||||
bool is_cond_br,
|
||||
LLVMValueRef cond_br_if,
|
||||
int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
|
||||
LLVMBasicBlockRef cond_br_else_block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -24,4 +22,3 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_EXCEPTION_H_ */
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
#include "aot_emit_table.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
#define ADD_BASIC_BLOCK(block, name) do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, \
|
||||
name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define ADD_BASIC_BLOCK(block, name) \
|
||||
do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
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 */
|
||||
if (!func_ctx->func_return_block) {
|
||||
if (!(func_ctx->func_return_block =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func, "func_ret"))) {
|
||||
if (!(func_ctx->func_return_block = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "func_ret"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
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. */
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->cur_exception,
|
||||
"exce_value"))
|
||||
|| !(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ,
|
||||
value, I8_ZERO, "cmp"))) {
|
||||
|| !(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, value, I8_ZERO,
|
||||
"cmp"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add check exection success block */
|
||||
if (!(check_exce_succ = LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_exce_succ"))) {
|
||||
if (!(check_exce_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_exce_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -78,8 +77,8 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr);
|
||||
/* Create condition br */
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp,
|
||||
check_exce_succ, func_ctx->func_return_block)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, check_exce_succ,
|
||||
func_ctx->func_return_block)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -100,16 +99,15 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!create_func_return_block(comp_ctx, func_ctx))
|
||||
return false;
|
||||
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE,
|
||||
res, I8_ZERO, "cmp"))) {
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, res, I8_ZERO,
|
||||
"cmp"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add check exection success block */
|
||||
if (!(check_call_succ = LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_call_succ"))) {
|
||||
if (!(check_call_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_call_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -119,8 +117,8 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_curr);
|
||||
/* Create condition br */
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp,
|
||||
check_call_succ, func_ctx->func_return_block)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, check_call_succ,
|
||||
func_ctx->func_return_block)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -132,10 +130,11 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
static bool
|
||||
call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef func_idx, AOTFuncType *aot_func_type,
|
||||
LLVMTypeRef *param_types, LLVMValueRef *param_values,
|
||||
uint32 param_count, uint32 param_cell_num,
|
||||
LLVMTypeRef ret_type, uint8 wasm_ret_type,
|
||||
LLVMValueRef *p_value_ret, LLVMValueRef *p_res)
|
||||
LLVMTypeRef *param_types,
|
||||
LLVMValueRef *param_values, uint32 param_count,
|
||||
uint32 param_cell_num, LLVMTypeRef ret_type,
|
||||
uint8 wasm_ret_type, LLVMValueRef *p_value_ret,
|
||||
LLVMValueRef *p_res)
|
||||
{
|
||||
LLVMTypeRef func_type, func_ptr_type, func_param_types[4];
|
||||
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;
|
||||
|
||||
/* prepare function type of aot_invoke_native */
|
||||
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
|
||||
func_param_types[1] = I32_TYPE; /* func_idx */
|
||||
func_param_types[2] = I32_TYPE; /* argc */
|
||||
func_param_types[3] = INT32_PTR_TYPE; /* argv */
|
||||
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
|
||||
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
|
||||
func_param_types[1] = I32_TYPE; /* func_idx */
|
||||
func_param_types[2] = I32_TYPE; /* argc */
|
||||
func_param_types[3] = INT32_PTR_TYPE; /* argv */
|
||||
if (!(func_type =
|
||||
LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
|
||||
aot_set_last_error("llvm add function type failed.");
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
func_index =
|
||||
aot_get_native_symbol_index(comp_ctx, func_name);
|
||||
func_index = aot_get_native_symbol_index(comp_ctx, func_name);
|
||||
if (func_index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -187,7 +186,7 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
else {
|
||||
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name))
|
||||
&& !(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.");
|
||||
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);
|
||||
if (!(elem_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->argv_buf, &elem_idx, 1, buf))
|
||||
if (!(elem_ptr = LLVMBuildInBoundsGEP(
|
||||
comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf))
|
||||
|| !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr,
|
||||
elem_ptr_type, buf))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -236,8 +236,8 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* call aot_invoke_native() function */
|
||||
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
|
||||
func_param_values, 4, "res"))) {
|
||||
if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 4,
|
||||
"res"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -249,13 +249,14 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(value_ret = LLVMBuildBitCast(comp_ctx->builder, func_ctx->argv_buf,
|
||||
ret_ptr_type, "argv_ret"))) {
|
||||
if (!(value_ret =
|
||||
LLVMBuildBitCast(comp_ctx->builder, func_ctx->argv_buf,
|
||||
ret_ptr_type, "argv_ret"))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
return false;
|
||||
}
|
||||
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
|
||||
"value_ret"))) {
|
||||
if (!(*p_value_ret =
|
||||
LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
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[1] = func_idx;
|
||||
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 2,
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
|
||||
"call_aot_alloc_frame"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(ret_value = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
|
||||
ret_value, I8_ZERO, "frame_alloc_ret"))) {
|
||||
if (!(ret_value = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, ret_value,
|
||||
I8_ZERO, "frame_alloc_ret"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
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_success, block_curr);
|
||||
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value,
|
||||
frame_alloc_success, frame_alloc_fail)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, frame_alloc_success,
|
||||
frame_alloc_fail)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -338,8 +338,7 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
param_values[0] = func_ctx->exec_env;
|
||||
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 1,
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 1,
|
||||
"call_aot_free_frame"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
|
@ -347,7 +346,7 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
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) */
|
||||
|
||||
static bool
|
||||
|
@ -363,17 +362,15 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(stack_bound = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->native_stack_bound,
|
||||
&callee_local_size, 1,
|
||||
"stack_bound"))) {
|
||||
if (!(stack_bound = LLVMBuildInBoundsGEP(
|
||||
comp_ctx->builder, func_ctx->native_stack_bound,
|
||||
&callee_local_size, 1, "stack_bound"))) {
|
||||
aot_set_last_error("llvm build inbound gep failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_stack"))) {
|
||||
if (!(check_stack = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_stack"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -381,14 +378,12 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(check_stack, block_curr);
|
||||
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT,
|
||||
func_ctx->last_alloca, stack_bound,
|
||||
"cmp"))) {
|
||||
func_ctx->last_alloca, stack_bound, "cmp"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_NATIVE_STACK_OVERFLOW,
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_NATIVE_STACK_OVERFLOW,
|
||||
true, cmp, check_stack)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -439,8 +434,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (func_idx < import_func_count)
|
||||
func_type = import_funcs[func_idx].func_type;
|
||||
else
|
||||
func_type = func_ctxes[func_idx - import_func_count]->
|
||||
aot_func->func_type;
|
||||
func_type =
|
||||
func_ctxes[func_idx - import_func_count]->aot_func->func_type;
|
||||
|
||||
/* Get param cell number */
|
||||
param_cell_num = func_type->param_cell_num;
|
||||
|
@ -467,8 +462,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
param_count = (int32)func_type->param_count;
|
||||
result_count = (int32)func_type->result_count;
|
||||
ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
||||
total_size = sizeof(LLVMValueRef) * (uint64)(param_count + 1
|
||||
+ ext_ret_count);
|
||||
total_size =
|
||||
sizeof(LLVMValueRef) * (uint64)(param_count + 1 + ext_ret_count);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(param_values = wasm_runtime_malloc((uint32)total_size))) {
|
||||
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++) {
|
||||
if (!(ext_ret_idx = I32_CONST(cell_num))
|
||||
|| !(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.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -511,9 +506,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i);
|
||||
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder,
|
||||
ext_ret_ptr, ext_ret_ptr_type,
|
||||
buf))) {
|
||||
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ext_ret_ptr,
|
||||
ext_ret_ptr_type, buf))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -552,13 +546,14 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* call aot_invoke_native() */
|
||||
if (!call_aot_invoke_native_func(comp_ctx, func_ctx, import_func_idx, func_type,
|
||||
param_types + 1, param_values + 1,
|
||||
param_count, param_cell_num,
|
||||
ret_type, wasm_ret_type, &value_ret, &res))
|
||||
if (!call_aot_invoke_native_func(
|
||||
comp_ctx, func_ctx, import_func_idx, func_type, param_types + 1,
|
||||
param_values + 1, param_count, param_cell_num, ret_type,
|
||||
wasm_ret_type, &value_ret, &res))
|
||||
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))
|
||||
goto fail;
|
||||
}
|
||||
|
@ -567,7 +562,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMTypeRef func_ptr_type;
|
||||
|
||||
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.");
|
||||
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;
|
||||
}
|
||||
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
|
||||
&& !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num))
|
||||
goto fail;
|
||||
|
||||
/* Call the function */
|
||||
if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values,
|
||||
(uint32)param_count + 1 + ext_ret_count,
|
||||
(func_type->result_count > 0
|
||||
? "call" : "")))) {
|
||||
if (!(value_ret =
|
||||
LLVMBuildCall(comp_ctx->builder, func, param_values,
|
||||
(uint32)param_count + 1 + ext_ret_count,
|
||||
(func_type->result_count > 0 ? "call" : "")))) {
|
||||
aot_set_last_error("LLVM build call failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
||||
if (tail_call)
|
||||
LLVMSetTailCall(value_ret, true);
|
||||
|
||||
/* Check whether there was exception thrown when executing the function */
|
||||
if (!tail_call
|
||||
&& !check_exception_thrown(comp_ctx, func_ctx))
|
||||
/* Check whether there was exception thrown when executing
|
||||
the function */
|
||||
if (!tail_call && !check_exception_thrown(comp_ctx, func_ctx))
|
||||
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 */
|
||||
for (i = 0; i < ext_ret_count; i++) {
|
||||
snprintf(buf, sizeof(buf), "func%d_ext_ret%d", func_idx, i);
|
||||
if (!(ext_ret = LLVMBuildLoad(comp_ctx->builder,
|
||||
param_values[1 + param_count + i],
|
||||
buf))) {
|
||||
if (!(ext_ret =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
param_values[1 + param_count + i], buf))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -642,12 +639,14 @@ fail:
|
|||
|
||||
static bool
|
||||
call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
AOTFuncType *aot_func_type, LLVMValueRef func_type_idx,
|
||||
LLVMValueRef table_idx, LLVMValueRef table_elem_idx,
|
||||
LLVMTypeRef *param_types, LLVMValueRef *param_values,
|
||||
uint32 param_count, uint32 param_cell_num,
|
||||
uint32 result_count, uint8 *wasm_ret_types,
|
||||
LLVMValueRef *value_rets, LLVMValueRef *p_res)
|
||||
AOTFuncType *aot_func_type,
|
||||
LLVMValueRef func_type_idx, LLVMValueRef table_idx,
|
||||
LLVMValueRef table_elem_idx,
|
||||
LLVMTypeRef *param_types,
|
||||
LLVMValueRef *param_values, uint32 param_count,
|
||||
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 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;
|
||||
|
||||
/* prepare function type of aot_call_indirect */
|
||||
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
|
||||
func_param_types[1] = I32_TYPE; /* table_idx */
|
||||
func_param_types[2] = I32_TYPE; /* table_elem_idx */
|
||||
func_param_types[3] = I32_TYPE; /* argc */
|
||||
func_param_types[4] = INT32_PTR_TYPE; /* argv */
|
||||
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
|
||||
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
|
||||
func_param_types[1] = I32_TYPE; /* table_idx */
|
||||
func_param_types[2] = I32_TYPE; /* table_elem_idx */
|
||||
func_param_types[3] = I32_TYPE; /* argc */
|
||||
func_param_types[4] = INT32_PTR_TYPE; /* argv */
|
||||
if (!(func_type =
|
||||
LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
|
||||
aot_set_last_error("llvm add function type failed.");
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
func_index =
|
||||
aot_get_native_symbol_index(comp_ctx, func_name);
|
||||
func_index = aot_get_native_symbol_index(comp_ctx, func_name);
|
||||
if (func_index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -699,15 +698,16 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
else {
|
||||
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name))
|
||||
&& !(func = LLVMAddFunction(comp_ctx->module,
|
||||
func_name, func_type))) {
|
||||
&& !(func =
|
||||
LLVMAddFunction(comp_ctx->module, func_name, func_type))) {
|
||||
aot_set_last_error("add LLVM function failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
aot_set_last_error("prepare native arguments failed: "
|
||||
"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);
|
||||
if (!(elem_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->argv_buf, &elem_idx, 1, buf))
|
||||
if (!(elem_ptr = LLVMBuildInBoundsGEP(
|
||||
comp_ctx->builder, func_ctx->argv_buf, &elem_idx, 1, buf))
|
||||
|| !(elem_ptr = LLVMBuildBitCast(comp_ctx->builder, elem_ptr,
|
||||
elem_ptr_type, buf))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
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.");
|
||||
return false;
|
||||
}
|
||||
|
@ -752,8 +753,8 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* call aot_call_indirect() function */
|
||||
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
|
||||
func_param_values, 5, "res"))) {
|
||||
if (!(res = LLVMBuildCall(comp_ctx->builder, func, func_param_values, 5,
|
||||
"res"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
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);
|
||||
if (!(ret_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->argv_buf, &ret_idx, 1, buf))
|
||||
if (!(ret_ptr = LLVMBuildInBoundsGEP(
|
||||
comp_ctx->builder, func_ctx->argv_buf, &ret_idx, 1, buf))
|
||||
|| !(ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ret_ptr,
|
||||
ret_ptr_type, buf))) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (!(table_size_const =
|
||||
LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst, &offset, 1,
|
||||
"cur_size_i8p"))) {
|
||||
if (!(table_size_const = LLVMBuildGEP(comp_ctx->builder, func_ctx->aot_inst,
|
||||
&offset, 1, "cur_size_i8p"))) {
|
||||
HANDLE_FAILURE("LLVMBuildGEP");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(table_size_const =
|
||||
LLVMBuildBitCast(comp_ctx->builder, table_size_const,
|
||||
INT32_PTR_TYPE, "cur_siuze_i32p"))) {
|
||||
LLVMBuildBitCast(comp_ctx->builder, table_size_const,
|
||||
INT32_PTR_TYPE, "cur_siuze_i32p"))) {
|
||||
HANDLE_FAILURE("LLVMBuildBitCast");
|
||||
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");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check if (uint32)elem index >= table size */
|
||||
if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE,
|
||||
elem_idx, table_size_const,
|
||||
"cmp_elem_idx"))) {
|
||||
if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx,
|
||||
table_size_const, "cmp_elem_idx"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Throw exception if elem index >= table size */
|
||||
if (!(check_elem_idx_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_elem_idx_succ"))) {
|
||||
if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -885,8 +883,8 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(check_elem_idx_succ,
|
||||
LLVMGetInsertBlock(comp_ctx->builder));
|
||||
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_UNDEFINED_ELEMENT,
|
||||
true, cmp_elem_idx, check_elem_idx_succ)))
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx, EXCE_UNDEFINED_ELEMENT, true,
|
||||
cmp_elem_idx, check_elem_idx_succ)))
|
||||
goto fail;
|
||||
|
||||
/* load data as i32* */
|
||||
|
@ -909,31 +907,28 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* Load function index */
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx,
|
||||
1, "table_elem"))) {
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
|
||||
"table_elem"))) {
|
||||
HANDLE_FAILURE("LLVMBuildNUWAdd");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(func_idx = LLVMBuildLoad(comp_ctx->builder,
|
||||
table_elem, "func_idx"))) {
|
||||
if (!(func_idx =
|
||||
LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check if func_idx == -1 */
|
||||
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ,
|
||||
func_idx, I32_NEG_ONE,
|
||||
"cmp_func_idx"))) {
|
||||
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntEQ, func_idx,
|
||||
I32_NEG_ONE, "cmp_func_idx"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Throw exception if func_idx == -1 */
|
||||
if (!(check_func_idx_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_func_idx_succ"))) {
|
||||
if (!(check_func_idx_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_func_idx_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -946,33 +941,29 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
|
||||
/* Load function type index */
|
||||
if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->func_type_indexes,
|
||||
&func_idx, 1,
|
||||
"ftype_idx_ptr"))) {
|
||||
if (!(ftype_idx_ptr = LLVMBuildInBoundsGEP(
|
||||
comp_ctx->builder, func_ctx->func_type_indexes, &func_idx, 1,
|
||||
"ftype_idx_ptr"))) {
|
||||
aot_set_last_error("llvm build inbounds gep failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(ftype_idx = LLVMBuildLoad(comp_ctx->builder, ftype_idx_ptr,
|
||||
"ftype_idx"))) {
|
||||
if (!(ftype_idx =
|
||||
LLVMBuildLoad(comp_ctx->builder, ftype_idx_ptr, "ftype_idx"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check if function type index not equal */
|
||||
if (!(cmp_ftype_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE,
|
||||
ftype_idx, ftype_idx_const,
|
||||
"cmp_ftype_idx"))) {
|
||||
if (!(cmp_ftype_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, ftype_idx,
|
||||
ftype_idx_const, "cmp_ftype_idx"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Throw exception if ftype_idx != ftype_idx_const */
|
||||
if (!(check_ftype_idx_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_ftype_idx_succ"))) {
|
||||
if (!(check_ftype_idx_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_ftype_idx_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -981,17 +972,17 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMGetInsertBlock(comp_ctx->builder));
|
||||
|
||||
if (!(aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_INVALID_FUNCTION_TYPE_INDEX,
|
||||
true, cmp_ftype_idx, check_ftype_idx_succ)))
|
||||
EXCE_INVALID_FUNCTION_TYPE_INDEX, true,
|
||||
cmp_ftype_idx, check_ftype_idx_succ)))
|
||||
goto fail;
|
||||
|
||||
/* Initialize parameter types of the LLVM function */
|
||||
total_param_count = 1 + func_param_count;
|
||||
|
||||
/* Extra function results' addresses (except the first one) are
|
||||
* appended to aot function parameters. */
|
||||
appended to aot function parameters. */
|
||||
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;
|
||||
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]);
|
||||
|
||||
for (i = 1; i < func_result_count; i++, j++) {
|
||||
param_types[j] =
|
||||
TO_LLVM_TYPE(func_type->types[func_param_count + i]);
|
||||
param_types[j] = TO_LLVM_TYPE(func_type->types[func_param_count + i]);
|
||||
if (!(param_types[j] = LLVMPointerType(param_types[j], 0))) {
|
||||
aot_set_last_error("llvm get pointer type failed.");
|
||||
goto fail;
|
||||
|
@ -1048,25 +1038,24 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
CHECK_LLVM_CONST(ext_ret_offset);
|
||||
|
||||
snprintf(buf, sizeof(buf), "ext_ret%d_ptr", i - 1);
|
||||
if (!(ext_ret_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
func_ctx->argv_buf,
|
||||
&ext_ret_offset, 1, buf))) {
|
||||
if (!(ext_ret_ptr =
|
||||
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->argv_buf,
|
||||
&ext_ret_offset, 1, buf))) {
|
||||
aot_set_last_error("llvm build GEP failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ext_ret_ptr_type = param_types[func_param_count + i];
|
||||
snprintf(buf, sizeof(buf), "ext_ret%d_ptr_cast", i - 1);
|
||||
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder,
|
||||
ext_ret_ptr, ext_ret_ptr_type,
|
||||
buf))) {
|
||||
if (!(ext_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, ext_ret_ptr,
|
||||
ext_ret_ptr_type, buf))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
param_values[func_param_count + i] = ext_ret_ptr;
|
||||
ext_cell_num += wasm_value_type_cell_num(
|
||||
func_type->types[func_param_count + i]);
|
||||
ext_cell_num +=
|
||||
wasm_value_type_cell_num(func_type->types[func_param_count + i]);
|
||||
}
|
||||
|
||||
if (ext_cell_num > 64) {
|
||||
|
@ -1091,15 +1080,12 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
#endif
|
||||
|
||||
/* Add basic blocks */
|
||||
block_call_import =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func,
|
||||
"call_import");
|
||||
block_call_non_import =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func,
|
||||
"call_non_import");
|
||||
block_return =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func,
|
||||
"func_return");
|
||||
block_call_import = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "call_import");
|
||||
block_call_non_import = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "call_non_import");
|
||||
block_return = LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func, "func_return");
|
||||
if (!block_call_import || !block_call_non_import || !block_return) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
goto fail;
|
||||
|
@ -1114,17 +1100,16 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
CHECK_LLVM_CONST(import_func_count);
|
||||
|
||||
/* Check if func_idx < import_func_count */
|
||||
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT,
|
||||
func_idx, import_func_count,
|
||||
"cmp_func_idx"))) {
|
||||
if (!(cmp_func_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, func_idx,
|
||||
import_func_count, "cmp_func_idx"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* If func_idx < import_func_count, jump to call import block,
|
||||
else jump to call non-import block */
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp_func_idx,
|
||||
block_call_import, block_call_non_import)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp_func_idx, block_call_import,
|
||||
block_call_non_import)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
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++) {
|
||||
LLVMTypeRef tmp_type =
|
||||
TO_LLVM_TYPE(func_type->types[func_param_count + i]);
|
||||
if (!(result_phis[i] = LLVMBuildPhi(comp_ctx->builder,
|
||||
tmp_type, "phi"))) {
|
||||
if (!(result_phis[i] =
|
||||
LLVMBuildPhi(comp_ctx->builder, tmp_type, "phi"))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1174,13 +1159,10 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!call_aot_call_indirect_func(comp_ctx, func_ctx,
|
||||
func_type, ftype_idx,
|
||||
tbl_idx_value, elem_idx,
|
||||
param_types + 1, param_values + 1,
|
||||
func_param_count, param_cell_num,
|
||||
func_result_count, wasm_ret_types,
|
||||
value_rets, &res))
|
||||
if (!call_aot_call_indirect_func(
|
||||
comp_ctx, func_ctx, func_type, ftype_idx, tbl_idx_value, elem_idx,
|
||||
param_types + 1, param_values + 1, func_param_count, param_cell_num,
|
||||
func_result_count, wasm_ret_types, value_rets, &res))
|
||||
goto fail;
|
||||
|
||||
/* 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
|
||||
&& !check_stack_boundary(comp_ctx, func_ctx,
|
||||
param_cell_num + ext_cell_num + 1
|
||||
/* Reserve some local variables */
|
||||
+ 16))
|
||||
param_cell_num + ext_cell_num
|
||||
+ 1
|
||||
/* Reserve some local variables */
|
||||
+ 16))
|
||||
goto fail;
|
||||
|
||||
/* Load function pointer */
|
||||
if (!(func_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs,
|
||||
&func_idx, 1, "func_ptr_tmp"))) {
|
||||
if (!(func_ptr =
|
||||
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->func_ptrs,
|
||||
&func_idx, 1, "func_ptr_tmp"))) {
|
||||
aot_set_last_error("llvm build inbounds gep failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1219,24 +1203,22 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!(llvm_func_type = LLVMFunctionType(ret_type, param_types,
|
||||
total_param_count, false))
|
||||
if (!(llvm_func_type =
|
||||
LLVMFunctionType(ret_type, param_types, total_param_count, false))
|
||||
|| !(llvm_func_ptr_type = LLVMPointerType(llvm_func_type, 0))) {
|
||||
aot_set_last_error("llvm add function type failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(func = LLVMBuildBitCast(comp_ctx->builder,
|
||||
func_ptr, llvm_func_ptr_type,
|
||||
"indirect_func"))) {
|
||||
if (!(func = LLVMBuildBitCast(comp_ctx->builder, func_ptr,
|
||||
llvm_func_ptr_type, "indirect_func"))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, total_param_count,
|
||||
func_result_count > 0
|
||||
? "ret" : ""))) {
|
||||
if (!(value_ret = LLVMBuildCall(comp_ctx->builder, func, param_values,
|
||||
total_param_count,
|
||||
func_result_count > 0 ? "ret" : ""))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
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 */
|
||||
for (i = 1; i < func_result_count; i++) {
|
||||
snprintf(buf, sizeof(buf), "ext_ret%d", i - 1);
|
||||
if (!(ext_ret = LLVMBuildLoad(comp_ctx->builder,
|
||||
param_values[func_param_count + i],
|
||||
buf))) {
|
||||
if (!(ext_ret =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
param_values[func_param_count + i], buf))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1333,8 +1315,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx)
|
||||
{
|
||||
LLVMValueRef ref_idx;
|
||||
|
|
|
@ -17,10 +17,8 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
uint32 func_idx, bool tail_call);
|
||||
|
||||
bool
|
||||
aot_compile_op_call_indirect(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 type_idx,
|
||||
uint32 tbl_idx);
|
||||
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_idx, uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
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);
|
||||
|
||||
bool
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx);
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_FUNCTION_H_ */
|
||||
|
||||
|
|
|
@ -7,33 +7,33 @@
|
|||
#include "aot_emit_exception.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
#define BUILD_ICMP(op, left, right, res, name) do { \
|
||||
if (!(res = LLVMBuildICmp(comp_ctx->builder, op, \
|
||||
left, right, name))) { \
|
||||
aot_set_last_error("llvm build icmp failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_ICMP(op, left, right, res, name) \
|
||||
do { \
|
||||
if (!(res = \
|
||||
LLVMBuildICmp(comp_ctx->builder, op, left, right, name))) { \
|
||||
aot_set_last_error("llvm build icmp failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_OP(Op, left, right, res, name) do { \
|
||||
if (!(res = LLVMBuild##Op(comp_ctx->builder, \
|
||||
left, right, name))) { \
|
||||
aot_set_last_error("llvm build " #Op " fail."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_OP(Op, left, right, res, name) \
|
||||
do { \
|
||||
if (!(res = LLVMBuild##Op(comp_ctx->builder, left, right, name))) { \
|
||||
aot_set_last_error("llvm build " #Op " fail."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ADD_BASIC_BLOCK(block, name) do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, \
|
||||
name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define ADD_BASIC_BLOCK(block, name) \
|
||||
do { \
|
||||
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
|
||||
func_ctx->func, name))) { \
|
||||
aot_set_last_error("llvm add basic block failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_BUILD_POS(block) \
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
|
||||
#define SET_BUILD_POS(block) LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
|
||||
|
||||
static LLVMValueRef
|
||||
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)
|
||||
return mem_check_bound;
|
||||
|
||||
if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder,
|
||||
mem_check_bound,
|
||||
if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder, mem_check_bound,
|
||||
"mem_check_bound"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
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;
|
||||
#endif
|
||||
|
||||
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64))
|
||||
? true : false;
|
||||
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
|
||||
|
||||
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
|
||||
|| is_shared_memory
|
||||
#endif
|
||||
) {
|
||||
) {
|
||||
mem_base_addr = func_ctx->mem_info[0].mem_base_addr;
|
||||
}
|
||||
else {
|
||||
if (!(mem_base_addr =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_base_addr,
|
||||
"mem_base"))) {
|
||||
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_base_addr,
|
||||
"mem_base"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
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) {
|
||||
/* aot_value is freed in the following POP_I32(addr),
|
||||
so save its fields here for further use */
|
||||
|
@ -136,12 +134,12 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
&& !LLVMIsPoison(addr)
|
||||
#endif
|
||||
) {
|
||||
uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(addr)
|
||||
+ (uint64)offset;
|
||||
uint64 mem_offset =
|
||||
(uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset;
|
||||
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 =
|
||||
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;
|
||||
|
||||
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 (!(offset_const = LLVMBuildZExt(comp_ctx->builder, offset_const,
|
||||
I64_TYPE, "offset_i64"))
|
||||
|| !(addr = LLVMBuildZExt(comp_ctx->builder, addr,
|
||||
I64_TYPE, "addr_i64"))) {
|
||||
|| !(addr = LLVMBuildZExt(comp_ctx->builder, addr, I64_TYPE,
|
||||
"addr_i64"))) {
|
||||
aot_set_last_error("llvm build zero extend failed.");
|
||||
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,
|
||||
offset, bytes))) {
|
||||
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) {
|
||||
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");
|
||||
LLVMMoveBasicBlockAfter(check_succ, block_curr);
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
||||
true, cmp, check_succ)) {
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
|
||||
check_succ)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -196,7 +194,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (!(mem_check_bound =
|
||||
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
|
||||
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -215,8 +213,8 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(check_succ, block_curr);
|
||||
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
||||
true, cmp, check_succ)) {
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
|
||||
check_succ)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -240,55 +238,60 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define BUILD_PTR_CAST(ptr_type) do { \
|
||||
if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr,\
|
||||
ptr_type, "data_ptr"))) {\
|
||||
aot_set_last_error("llvm build bit cast failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_PTR_CAST(ptr_type) \
|
||||
do { \
|
||||
if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr, ptr_type, \
|
||||
"data_ptr"))) { \
|
||||
aot_set_last_error("llvm build bit cast failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_LOAD() do { \
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, \
|
||||
"data"))) { \
|
||||
aot_set_last_error("llvm build load failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(value, 1); \
|
||||
} while (0)
|
||||
#define BUILD_LOAD() \
|
||||
do { \
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \
|
||||
aot_set_last_error("llvm build load failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(value, 1); \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_TRUNC(value, data_type) do { \
|
||||
if (!(value = LLVMBuildTrunc(comp_ctx->builder, value, \
|
||||
data_type, "val_trunc"))){ \
|
||||
aot_set_last_error("llvm build trunc failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_TRUNC(value, data_type) \
|
||||
do { \
|
||||
if (!(value = LLVMBuildTrunc(comp_ctx->builder, value, data_type, \
|
||||
"val_trunc"))) { \
|
||||
aot_set_last_error("llvm build trunc failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_STORE() do { \
|
||||
LLVMValueRef res; \
|
||||
if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \
|
||||
aot_set_last_error("llvm build store failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(res, 1); \
|
||||
} while (0)
|
||||
#define BUILD_STORE() \
|
||||
do { \
|
||||
LLVMValueRef res; \
|
||||
if (!(res = LLVMBuildStore(comp_ctx->builder, value, maddr))) { \
|
||||
aot_set_last_error("llvm build store failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(res, 1); \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_SIGN_EXT(dst_type) do { \
|
||||
if (!(value = LLVMBuildSExt(comp_ctx->builder, value, \
|
||||
dst_type, "data_s_ext"))) { \
|
||||
aot_set_last_error("llvm build sign ext failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_SIGN_EXT(dst_type) \
|
||||
do { \
|
||||
if (!(value = LLVMBuildSExt(comp_ctx->builder, value, dst_type, \
|
||||
"data_s_ext"))) { \
|
||||
aot_set_last_error("llvm build sign ext failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_ZERO_EXT(dst_type) do { \
|
||||
if (!(value = LLVMBuildZExt(comp_ctx->builder, value, \
|
||||
dst_type, "data_z_ext"))) { \
|
||||
aot_set_last_error("llvm build zero ext failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
#define BUILD_ZERO_EXT(dst_type) \
|
||||
do { \
|
||||
if (!(value = LLVMBuildZExt(comp_ctx->builder, value, dst_type, \
|
||||
"data_z_ext"))) { \
|
||||
aot_set_last_error("llvm build zero ext failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool
|
||||
|
@ -303,8 +306,8 @@ check_memory_alignment(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
CHECK_LLVM_CONST(align_mask);
|
||||
|
||||
/* Convert pointer to int */
|
||||
if (!(addr = LLVMBuildPtrToInt(comp_ctx->builder, addr,
|
||||
I32_TYPE, "address"))) {
|
||||
if (!(addr = LLVMBuildPtrToInt(comp_ctx->builder, addr, I32_TYPE,
|
||||
"address"))) {
|
||||
aot_set_last_error("llvm build ptr to int failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -317,9 +320,8 @@ check_memory_alignment(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
ADD_BASIC_BLOCK(check_align_succ, "check_align_succ");
|
||||
LLVMMoveBasicBlockAfter(check_align_succ, block_curr);
|
||||
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_UNALIGNED_ATOMIC,
|
||||
true, res, check_align_succ)) {
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_UNALIGNED_ATOMIC, true,
|
||||
res, check_align_succ)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -330,39 +332,40 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#define BUILD_ATOMIC_LOAD(align) do { \
|
||||
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
|
||||
goto fail; \
|
||||
} \
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, \
|
||||
"data"))) { \
|
||||
aot_set_last_error("llvm build load failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(value, 1 << align); \
|
||||
LLVMSetVolatile(value, true); \
|
||||
LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \
|
||||
} while (0)
|
||||
#define BUILD_ATOMIC_LOAD(align) \
|
||||
do { \
|
||||
if (!(check_memory_alignment(comp_ctx, func_ctx, maddr, align))) { \
|
||||
goto fail; \
|
||||
} \
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, maddr, "data"))) { \
|
||||
aot_set_last_error("llvm build load failed."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(value, 1 << align); \
|
||||
LLVMSetVolatile(value, true); \
|
||||
LLVMSetOrdering(value, LLVMAtomicOrderingSequentiallyConsistent); \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_ATOMIC_STORE(align) do { \
|
||||
LLVMValueRef res; \
|
||||
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."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(res, 1 << align); \
|
||||
LLVMSetVolatile(res, true); \
|
||||
LLVMSetOrdering(res, LLVMAtomicOrderingSequentiallyConsistent); \
|
||||
} while (0)
|
||||
#define BUILD_ATOMIC_STORE(align) \
|
||||
do { \
|
||||
LLVMValueRef res; \
|
||||
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."); \
|
||||
goto fail; \
|
||||
} \
|
||||
LLVMSetAlignment(res, 1 << align); \
|
||||
LLVMSetVolatile(res, true); \
|
||||
LLVMSetOrdering(res, LLVMAtomicOrderingSequentiallyConsistent); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
bool sign, bool atomic)
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic)
|
||||
{
|
||||
LLVMValueRef maddr, value = NULL;
|
||||
|
||||
|
@ -413,8 +416,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
bool sign, bool atomic)
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else {
|
||||
if (!(mem_size =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_cur_page_count_addr,
|
||||
"mem_size"))) {
|
||||
if (!(mem_size = LLVMBuildLoad(
|
||||
comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_cur_page_count_addr, "mem_size"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -694,7 +696,7 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
return false;
|
||||
}
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -707,8 +709,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
char *func_name = "aot_enlarge_memory";
|
||||
/* AOT mode, delcare the function */
|
||||
if (!(func = LLVMGetNamedFunction(comp_ctx->module, func_name))
|
||||
&& !(func = LLVMAddFunction(comp_ctx->module,
|
||||
func_name, func_type))) {
|
||||
&& !(func =
|
||||
LLVMAddFunction(comp_ctx->module, func_name, func_type))) {
|
||||
aot_set_last_error("llvm add function failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -717,8 +719,8 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
/* Call function aot_enlarge_memory() */
|
||||
param_values[0] = func_ctx->aot_inst;
|
||||
param_values[1] = delta;
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 2, "call"))) {
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
|
||||
"call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
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");
|
||||
|
||||
/* ret_value = ret_value == true ? delta : pre_page_count */
|
||||
if (!(ret_value = LLVMBuildSelect(comp_ctx->builder, ret_value,
|
||||
mem_size, I32_NEG_ONE,
|
||||
"mem_grow_ret"))) {
|
||||
if (!(ret_value = LLVMBuildSelect(comp_ctx->builder, ret_value, mem_size,
|
||||
I32_NEG_ONE, "mem_grow_ret"))) {
|
||||
aot_set_last_error("llvm build select failed.");
|
||||
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;
|
||||
}
|
||||
else {
|
||||
if (!(mem_base_addr =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_base_addr,
|
||||
"mem_base"))) {
|
||||
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_base_addr,
|
||||
"mem_base"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -785,16 +785,14 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(offset);
|
||||
uint64 mem_len = (uint64)LLVMConstIntGetZExtValue(bytes);
|
||||
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 =
|
||||
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;
|
||||
if (mem_data_size > 0
|
||||
&& mem_offset + mem_len <= mem_data_size) {
|
||||
if (mem_data_size > 0 && mem_offset + mem_len <= mem_data_size) {
|
||||
/* inside memory space */
|
||||
/* maddr = mem_base_addr + moffset */
|
||||
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder,
|
||||
mem_base_addr,
|
||||
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
|
||||
&offset, 1, "maddr"))) {
|
||||
aot_set_last_error("llvm build add failed.");
|
||||
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;
|
||||
}
|
||||
else {
|
||||
if (!(mem_size =
|
||||
LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_data_size_addr,
|
||||
"mem_size"))) {
|
||||
if (!(mem_size = LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->mem_info[0].mem_data_size_addr,
|
||||
"mem_size"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -819,16 +816,17 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
ADD_BASIC_BLOCK(check_succ, "check_succ");
|
||||
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");
|
||||
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_ICMP(LLVMIntUGT, max_addr, mem_size, cmp,
|
||||
"cmp_max_mem_addr");
|
||||
BUILD_ICMP(LLVMIntUGT, max_addr, mem_size, cmp, "cmp_max_mem_addr");
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
||||
true, cmp, check_succ)) {
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
|
||||
check_succ)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -874,8 +872,8 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
param_values[2] = offset;
|
||||
param_values[3] = len;
|
||||
param_values[4] = dst;
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 5, "call"))) {
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5,
|
||||
"call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -888,14 +886,14 @@ aot_compile_op_memory_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(mem_init_fail, block_curr);
|
||||
LLVMMoveBasicBlockAfter(init_success, block_curr);
|
||||
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value,
|
||||
init_success, mem_init_fail)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, ret_value, init_success,
|
||||
mem_init_fail)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
|
||||
goto fail;
|
||||
|
@ -927,8 +925,8 @@ aot_compile_op_data_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Call function aot_data_drop() */
|
||||
param_values[0] = func_ctx->aot_inst;
|
||||
param_values[1] = seg;
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 2, "call"))) {
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 2,
|
||||
"call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -947,18 +945,16 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
POP_I32(src);
|
||||
POP_I32(dst);
|
||||
|
||||
if (!(src_addr =
|
||||
check_bulk_memory_overflow(comp_ctx, func_ctx, src, len)))
|
||||
if (!(src_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, src, len)))
|
||||
return false;
|
||||
|
||||
if (!(dst_addr =
|
||||
check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
return false;
|
||||
|
||||
/* TODO: lookup func ptr of "memmove" to call for XIP mode */
|
||||
|
||||
if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1,
|
||||
src_addr, 1, len))) {
|
||||
if (!(res = LLVMBuildMemMove(comp_ctx->builder, dst_addr, 1, src_addr, 1,
|
||||
len))) {
|
||||
aot_set_last_error("llvm build memmove failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -976,20 +972,18 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
POP_I32(val);
|
||||
POP_I32(dst);
|
||||
|
||||
if (!(dst_addr =
|
||||
check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
|
||||
return false;
|
||||
|
||||
if (!(val = LLVMBuildIntCast2(comp_ctx->builder, val, INT8_TYPE,
|
||||
true, "mem_set_value"))) {
|
||||
if (!(val = LLVMBuildIntCast2(comp_ctx->builder, val, INT8_TYPE, true,
|
||||
"mem_set_value"))) {
|
||||
aot_set_last_error("llvm build int cast2 failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO: lookup func ptr of "memset" to call for XIP mode */
|
||||
|
||||
if (!(res = LLVMBuildMemSet(comp_ctx->builder, dst_addr,
|
||||
val, len, 1))) {
|
||||
if (!(res = LLVMBuildMemSet(comp_ctx->builder, dst_addr, val, len, 1))) {
|
||||
aot_set_last_error("llvm build memset failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -1001,11 +995,9 @@ fail:
|
|||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type,
|
||||
uint32 align, uint32 offset,
|
||||
uint32 bytes)
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, result;
|
||||
|
||||
|
@ -1042,25 +1034,24 @@ aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildAtomicRMW(comp_ctx->builder,
|
||||
atomic_op, maddr, value,
|
||||
LLVMAtomicOrderingSequentiallyConsistent, false))) {
|
||||
if (!(result = LLVMBuildAtomicRMW(
|
||||
comp_ctx->builder, atomic_op, maddr, value,
|
||||
LLVMAtomicOrderingSequentiallyConsistent, false))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
LLVMSetVolatile(result, true);
|
||||
|
||||
if (op_type == VALUE_TYPE_I32) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result,
|
||||
I32_TYPE, "result_i32"))) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
|
||||
"result_i32"))) {
|
||||
goto fail;
|
||||
}
|
||||
PUSH_I32(result);
|
||||
}
|
||||
else {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result,
|
||||
I64_TYPE, "result_i64"))) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
|
||||
"result_i64"))) {
|
||||
goto fail;
|
||||
}
|
||||
PUSH_I64(result);
|
||||
|
@ -1073,9 +1064,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
AOTFuncContext *func_ctx, uint8 op_type,
|
||||
uint32 align, uint32 offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, expect, result;
|
||||
|
||||
|
@ -1120,34 +1110,32 @@ aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildAtomicCmpXchg(comp_ctx->builder, maddr, expect, value,
|
||||
LLVMAtomicOrderingSequentiallyConsistent,
|
||||
LLVMAtomicOrderingSequentiallyConsistent,
|
||||
false))) {
|
||||
if (!(result = LLVMBuildAtomicCmpXchg(
|
||||
comp_ctx->builder, maddr, expect, value,
|
||||
LLVMAtomicOrderingSequentiallyConsistent,
|
||||
LLVMAtomicOrderingSequentiallyConsistent, false))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
LLVMSetVolatile(result, true);
|
||||
|
||||
/* CmpXchg return {i32, i1} structure,
|
||||
we need to extrack the previous_value from the structure */
|
||||
if (!(result =
|
||||
LLVMBuildExtractValue(comp_ctx->builder,
|
||||
result, 0, "previous_value"))) {
|
||||
we need to extrack the previous_value from the structure */
|
||||
if (!(result = LLVMBuildExtractValue(comp_ctx->builder, result, 0,
|
||||
"previous_value"))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (op_type == VALUE_TYPE_I32) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result,
|
||||
I32_TYPE, "result_i32"))) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE,
|
||||
"result_i32"))) {
|
||||
goto fail;
|
||||
}
|
||||
PUSH_I32(result);
|
||||
}
|
||||
else {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result,
|
||||
I64_TYPE, "result_i64"))) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, I64_TYPE,
|
||||
"result_i64"))) {
|
||||
goto fail;
|
||||
}
|
||||
PUSH_I64(result);
|
||||
|
@ -1160,8 +1148,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
uint8 op_type, uint32 align, uint32 offset,
|
||||
uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, timeout, expect, cmp;
|
||||
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) {
|
||||
POP_I32(expect);
|
||||
is_wait64 = I8_CONST(false);
|
||||
if (!(expect =
|
||||
LLVMBuildZExt(comp_ctx->builder, expect,
|
||||
I64_TYPE, "expect_i64"))) {
|
||||
if (!(expect = LLVMBuildZExt(comp_ctx->builder, expect, I64_TYPE,
|
||||
"expect_i64"))) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -1208,8 +1195,8 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
param_values[2] = expect;
|
||||
param_values[3] = timeout;
|
||||
param_values[4] = is_wait64;
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 5, "call"))) {
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 5,
|
||||
"call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -1222,14 +1209,13 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMMoveBasicBlockAfter(wait_fail, block_curr);
|
||||
LLVMMoveBasicBlockAfter(wait_success, block_curr);
|
||||
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp,
|
||||
wait_success, wait_fail)) {
|
||||
if (!LLVMBuildCondBr(comp_ctx->builder, cmp, wait_success, wait_fail)) {
|
||||
aot_set_last_error("llvm build cond br failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
|
||||
goto fail;
|
||||
|
@ -1246,8 +1232,8 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes)
|
||||
AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
{
|
||||
LLVMValueRef maddr, value, count;
|
||||
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[1] = maddr;
|
||||
param_values[2] = count;
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func,
|
||||
param_values, 3, "call"))) {
|
||||
if (!(ret_value = LLVMBuildCall(comp_ctx->builder, func, param_values, 3,
|
||||
"call"))) {
|
||||
aot_set_last_error("llvm build call failed.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_op_i32_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
bool sign, bool atomic);
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes,
|
||||
bool sign, bool atomic);
|
||||
uint32 align, uint32 offset, uint32 bytes, bool sign,
|
||||
bool atomic);
|
||||
|
||||
bool
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
bool
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type,
|
||||
uint32 align, uint32 offset,
|
||||
uint32 bytes);
|
||||
aot_compile_op_atomic_rmw(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 atomic_op, uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compile_op_atomic_cmpxchg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
AOTFuncContext *func_ctx, uint8 op_type,
|
||||
uint32 align, uint32 offset, uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
uint8 op_type, uint32 align, uint32 offset,
|
||||
uint32 bytes);
|
||||
|
||||
bool
|
||||
aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset, uint32 bytes);
|
||||
AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 bytes);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -105,4 +104,3 @@ aot_compiler_op_atomic_notify(AOTCompContext *comp_ctx,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_MEMORY_H_ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,12 +31,14 @@ bool
|
|||
aot_compile_op_i64_popcnt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntArithmetic arith_op, uint8 **p_frame_ip);
|
||||
aot_compile_op_i32_arithmetic(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntArithmetic arith_op,
|
||||
uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntArithmetic arith_op, uint8 **p_frame_ip);
|
||||
aot_compile_op_i64_arithmetic(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, IntArithmetic arith_op,
|
||||
uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
bool
|
||||
|
@ -81,4 +85,3 @@ aot_compile_op_f64_copysign(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_NUMBERIC_H_ */
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
static bool
|
||||
pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef *p_value,
|
||||
bool is_32, uint8 *p_type)
|
||||
LLVMValueRef *p_value, bool is_32, uint8 *p_type)
|
||||
{
|
||||
AOTValue *aot_value;
|
||||
uint8 type;
|
||||
|
@ -22,14 +21,14 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
aot_value = aot_value_stack_pop
|
||||
(&func_ctx->block_stack.block_list_end->value_stack);
|
||||
aot_value =
|
||||
aot_value_stack_pop(&func_ctx->block_stack.block_list_end->value_stack);
|
||||
type = aot_value->type;
|
||||
|
||||
if (aot_value->type == VALUE_TYPE_I1) {
|
||||
if (!(aot_value->value =
|
||||
LLVMBuildZExt(comp_ctx->builder, aot_value->value,
|
||||
I32_TYPE, "val_s_ext"))) {
|
||||
LLVMBuildZExt(comp_ctx->builder, aot_value->value, I32_TYPE,
|
||||
"val_s_ext"))) {
|
||||
aot_set_last_error("llvm build sign ext failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -55,8 +54,7 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* !is_32: i64, f64 */
|
||||
if (!is_32
|
||||
&& !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
|
||||
if (!is_32 && !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
|
||||
aot_set_last_error("invalid WASM stack data type.");
|
||||
return false;
|
||||
}
|
||||
|
@ -64,7 +62,6 @@ pop_value_from_wasm_stack(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
aot_compile_op_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool is_drop_32)
|
||||
|
@ -84,8 +81,10 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
POP_COND(cond);
|
||||
|
||||
if (!pop_value_from_wasm_stack(comp_ctx, func_ctx, &val2, is_select_32, &val2_type)
|
||||
|| !pop_value_from_wasm_stack(comp_ctx, func_ctx, &val1, is_select_32, &val1_type))
|
||||
if (!pop_value_from_wasm_stack(comp_ctx, func_ctx, &val2, is_select_32,
|
||||
&val2_type)
|
||||
|| !pop_value_from_wasm_stack(comp_ctx, func_ctx, &val1, is_select_32,
|
||||
&val1_type))
|
||||
return false;
|
||||
|
||||
if (val1_type != val2_type) {
|
||||
|
@ -93,9 +92,8 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(selected = LLVMBuildSelect(comp_ctx->builder,
|
||||
cond, val1, val2,
|
||||
"select"))) {
|
||||
if (!(selected =
|
||||
LLVMBuildSelect(comp_ctx->builder, cond, val1, val2, "select"))) {
|
||||
aot_set_last_error("llvm build select failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -107,4 +105,3 @@ aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,10 @@ aot_compile_op_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_select(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool is_select_32);
|
||||
|
||||
bool is_select_32);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_PARAMETRIC_H_ */
|
||||
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
#include "aot_emit_exception.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
|
||||
uint64
|
||||
get_tbl_inst_offset(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
const AOTFuncContext *func_ctx, uint32 tbl_idx)
|
||||
{
|
||||
uint64 offset = 0, i = 0;
|
||||
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 */
|
||||
offset =
|
||||
offsetof(AOTModuleInstance, global_table_data.bytes)
|
||||
+ (uint64)comp_ctx->comp_data->memory_count * sizeof(AOTMemoryInstance)
|
||||
+ comp_ctx->comp_data->global_data_size;
|
||||
offsetof(AOTModuleInstance, global_table_data.bytes)
|
||||
+ (uint64)comp_ctx->comp_data->memory_count * sizeof(AOTMemoryInstance)
|
||||
+ comp_ctx->comp_data->global_data_size;
|
||||
|
||||
while (i < tbl_idx && i < comp_ctx->comp_data->import_table_count) {
|
||||
offset += offsetof(AOTTableInstance, data);
|
||||
|
@ -49,14 +47,13 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx,
|
|||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
|
||||
LLVMValueRef
|
||||
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMValueRef offset, tbl_inst;
|
||||
|
||||
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");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -73,8 +70,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_elem_drop(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_elem_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_seg_idx)
|
||||
{
|
||||
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 */
|
||||
if (!(ret_value =
|
||||
LLVMBuildCall(comp_ctx->builder, func, param_values, 2, ""))) {
|
||||
LLVMBuildCall(comp_ctx->builder, func, param_values, 2, ""))) {
|
||||
HANDLE_FAILURE("LLVMBuildCall");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -106,10 +102,8 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
aot_check_table_access(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx,
|
||||
LLVMValueRef elem_idx)
|
||||
aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx, LLVMValueRef elem_idx)
|
||||
{
|
||||
LLVMValueRef offset, tbl_sz, cmp_elem_idx;
|
||||
LLVMBasicBlockRef check_elem_idx_succ;
|
||||
|
@ -147,7 +141,7 @@ aot_check_table_access(AOTCompContext *comp_ctx,
|
|||
|
||||
/* Throw exception if elem index >= table size */
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -166,8 +160,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_get(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMValueRef elem_idx, offset, table_elem, func_idx;
|
||||
|
@ -198,14 +191,14 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
/* Load function index */
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx,
|
||||
1, "table_elem"))) {
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
|
||||
"table_elem"))) {
|
||||
HANDLE_FAILURE("LLVMBuildNUWAdd");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(func_idx =
|
||||
LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) {
|
||||
LLVMBuildLoad(comp_ctx->builder, table_elem, "func_idx"))) {
|
||||
HANDLE_FAILURE("LLVMBuildLoad");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -218,8 +211,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_set(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMValueRef val, elem_idx, offset, table_elem;
|
||||
|
@ -251,8 +243,8 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
/* Load function index */
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx,
|
||||
1, "table_elem"))) {
|
||||
if (!(table_elem = LLVMBuildGEP(comp_ctx->builder, table_elem, &elem_idx, 1,
|
||||
"table_elem"))) {
|
||||
HANDLE_FAILURE("LLVMBuildGEP");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -268,10 +260,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_init(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx,
|
||||
uint32 tbl_seg_idx)
|
||||
aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx, uint32 tbl_seg_idx)
|
||||
|
||||
{
|
||||
LLVMValueRef func, param_values[6], value;
|
||||
|
@ -318,10 +308,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_copy(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 src_tbl_idx,
|
||||
uint32 dst_tbl_idx)
|
||||
aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 src_tbl_idx, uint32 dst_tbl_idx)
|
||||
{
|
||||
LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
|
||||
LLVMValueRef func, param_values[6], value;
|
||||
|
@ -367,8 +355,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_size(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMValueRef offset, tbl_sz;
|
||||
|
@ -404,8 +391,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_grow(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
|
||||
|
@ -445,8 +431,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_table_fill(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx)
|
||||
{
|
||||
LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;
|
||||
|
|
|
@ -14,55 +14,43 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_op_elem_drop(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_elem_drop(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_seg_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_get(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_set(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_init(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx,
|
||||
uint32 tbl_seg_idx);
|
||||
aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx, uint32 tbl_seg_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_copy(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 src_tbl_idx,
|
||||
uint32 dst_tbl_idx);
|
||||
aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 src_tbl_idx, uint32 dst_tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_size(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_grow(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_table_fill(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
uint64
|
||||
get_tbl_inst_offset(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
const AOTFuncContext *func_ctx, uint32 tbl_idx);
|
||||
|
||||
LLVMValueRef
|
||||
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_get_tbl_inst(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 tbl_idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
#include "aot_emit_exception.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
#define CHECK_LOCAL(idx) do { \
|
||||
if (idx >= func_ctx->aot_func->func_type->param_count \
|
||||
+ func_ctx->aot_func->local_count) { \
|
||||
aot_set_last_error("local index out of range"); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_LOCAL(idx) \
|
||||
do { \
|
||||
if (idx >= func_ctx->aot_func->func_type->param_count \
|
||||
+ func_ctx->aot_func->local_count) { \
|
||||
aot_set_last_error("local index out of range"); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static uint8
|
||||
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;
|
||||
uint32 param_count = aot_func->func_type->param_count;
|
||||
return local_idx < param_count
|
||||
? aot_func->func_type->types[local_idx]
|
||||
: aot_func->local_types[local_idx - param_count];
|
||||
? aot_func->func_type->types[local_idx]
|
||||
: aot_func->local_types[local_idx - param_count];
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -36,8 +37,7 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
CHECK_LOCAL(local_idx);
|
||||
|
||||
snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#");
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder,
|
||||
func_ctx->locals[local_idx],
|
||||
if (!(value = LLVMBuildLoad(comp_ctx->builder, func_ctx->locals[local_idx],
|
||||
name))) {
|
||||
aot_set_last_error("llvm build load fail");
|
||||
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));
|
||||
|
||||
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->local_idx = local_idx;
|
||||
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));
|
||||
|
||||
if (!LLVMBuildStore(comp_ctx->builder,
|
||||
value,
|
||||
if (!LLVMBuildStore(comp_ctx->builder, value,
|
||||
func_ctx->locals[local_idx])) {
|
||||
aot_set_last_error("llvm build store fail");
|
||||
return false;
|
||||
|
@ -91,8 +91,7 @@ aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
POP(value, type);
|
||||
|
||||
if (!LLVMBuildStore(comp_ctx->builder,
|
||||
value,
|
||||
if (!LLVMBuildStore(comp_ctx->builder, value,
|
||||
func_ctx->locals[local_idx])) {
|
||||
aot_set_last_error("llvm build store fail");
|
||||
return false;
|
||||
|
@ -128,15 +127,16 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
global_type = comp_data->import_globals[global_idx].type;
|
||||
}
|
||||
else {
|
||||
global_offset = global_base_offset
|
||||
global_offset =
|
||||
global_base_offset
|
||||
+ comp_data->globals[global_idx - import_global_count].data_offset;
|
||||
global_type =
|
||||
comp_data->globals[global_idx - import_global_count].type;
|
||||
global_type = comp_data->globals[global_idx - import_global_count].type;
|
||||
}
|
||||
|
||||
offset = I32_CONST(global_offset);
|
||||
if (!(global_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
|
||||
&offset, 1, "global_ptr_tmp"))) {
|
||||
if (!(global_ptr =
|
||||
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
|
||||
&offset, 1, "global_ptr_tmp"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -164,15 +164,15 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr,
|
||||
ptr_type, "global_ptr"))) {
|
||||
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr, ptr_type,
|
||||
"global_ptr"))) {
|
||||
aot_set_last_error("llvm build bit cast failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_set) {
|
||||
if (!(global = LLVMBuildLoad(comp_ctx->builder,
|
||||
global_ptr, "global"))) {
|
||||
if (!(global =
|
||||
LLVMBuildLoad(comp_ctx->builder, global_ptr, "global"))) {
|
||||
aot_set_last_error("llvm build load failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -184,61 +184,56 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
POP(global, global_type);
|
||||
|
||||
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;
|
||||
LLVMValueRef cmp;
|
||||
|
||||
/* Add basic blocks */
|
||||
if (!(check_overflow_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_overflow_succ"))) {
|
||||
if (!(check_overflow_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func,
|
||||
"check_overflow_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
LLVMMoveBasicBlockAfter(check_overflow_succ, block_curr);
|
||||
|
||||
if (!(check_underflow_succ =
|
||||
LLVMAppendBasicBlockInContext(comp_ctx->context,
|
||||
func_ctx->func,
|
||||
"check_underflow_succ"))) {
|
||||
if (!(check_underflow_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func,
|
||||
"check_underflow_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
return false;
|
||||
}
|
||||
LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ);
|
||||
|
||||
/* Check aux stack overflow */
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE,
|
||||
global, func_ctx->aux_stack_bound,
|
||||
"cmp"))) {
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE, global,
|
||||
func_ctx->aux_stack_bound, "cmp"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
return false;
|
||||
}
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_AUX_STACK_OVERFLOW,
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_AUX_STACK_OVERFLOW,
|
||||
true, cmp, check_overflow_succ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check aux stack underflow */
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ);
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
|
||||
global, func_ctx->aux_stack_bottom,
|
||||
"cmp"))) {
|
||||
if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT, global,
|
||||
func_ctx->aux_stack_bottom, "cmp"))) {
|
||||
aot_set_last_error("llvm build icmp failed.");
|
||||
return false;
|
||||
}
|
||||
if (!aot_emit_exception(comp_ctx, func_ctx,
|
||||
EXCE_AUX_STACK_UNDERFLOW,
|
||||
true, cmp, check_underflow_succ)) {
|
||||
EXCE_AUX_STACK_UNDERFLOW, true, cmp,
|
||||
check_underflow_succ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVMPositionBuilderAtEnd(comp_ctx->builder, check_underflow_succ);
|
||||
}
|
||||
|
||||
if (!(res = LLVMBuildStore(comp_ctx->builder,
|
||||
global, global_ptr))) {
|
||||
if (!(res = LLVMBuildStore(comp_ctx->builder, global, global_ptr))) {
|
||||
aot_set_last_error("llvm build store failed.");
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,4 +37,3 @@ aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_EMIT_VARIABLE_H_ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,163 +33,162 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Value in the WASM operation stack, each stack element
|
||||
* is an LLVM value
|
||||
*/
|
||||
typedef struct AOTValue {
|
||||
struct AOTValue *next;
|
||||
struct AOTValue *prev;
|
||||
LLVMValueRef value;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64/VOID */
|
||||
uint8 type;
|
||||
bool is_local;
|
||||
uint32 local_idx;
|
||||
struct AOTValue *next;
|
||||
struct AOTValue *prev;
|
||||
LLVMValueRef value;
|
||||
/* VALUE_TYPE_I32/I64/F32/F64/VOID */
|
||||
uint8 type;
|
||||
bool is_local;
|
||||
uint32 local_idx;
|
||||
} AOTValue;
|
||||
|
||||
/**
|
||||
* Value stack, represents stack elements in a WASM block
|
||||
*/
|
||||
typedef struct AOTValueStack {
|
||||
AOTValue *value_list_head;
|
||||
AOTValue *value_list_end;
|
||||
AOTValue *value_list_head;
|
||||
AOTValue *value_list_end;
|
||||
} AOTValueStack;
|
||||
|
||||
typedef struct AOTBlock {
|
||||
struct AOTBlock *next;
|
||||
struct AOTBlock *prev;
|
||||
struct AOTBlock *next;
|
||||
struct AOTBlock *prev;
|
||||
|
||||
/* Block index */
|
||||
uint32 block_index;
|
||||
/* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
|
||||
uint32 label_type;
|
||||
/* Whether it is reachable */
|
||||
bool is_reachable;
|
||||
/* Whether skip translation of wasm else branch */
|
||||
bool skip_wasm_code_else;
|
||||
/* Block index */
|
||||
uint32 block_index;
|
||||
/* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
|
||||
uint32 label_type;
|
||||
/* Whether it is reachable */
|
||||
bool is_reachable;
|
||||
/* Whether skip translation of wasm else branch */
|
||||
bool skip_wasm_code_else;
|
||||
|
||||
/* code of else opcode of this block, if it is a IF block */
|
||||
uint8 *wasm_code_else;
|
||||
/* code end of this block */
|
||||
uint8 *wasm_code_end;
|
||||
/* code of else opcode of this block, if it is a IF block */
|
||||
uint8 *wasm_code_else;
|
||||
/* code end of this block */
|
||||
uint8 *wasm_code_end;
|
||||
|
||||
/* LLVM label points to code begin */
|
||||
LLVMBasicBlockRef llvm_entry_block;
|
||||
/* LLVM label points to code else */
|
||||
LLVMBasicBlockRef llvm_else_block;
|
||||
/* LLVM label points to code end */
|
||||
LLVMBasicBlockRef llvm_end_block;
|
||||
/* LLVM label points to code begin */
|
||||
LLVMBasicBlockRef llvm_entry_block;
|
||||
/* LLVM label points to code else */
|
||||
LLVMBasicBlockRef llvm_else_block;
|
||||
/* LLVM label points to code end */
|
||||
LLVMBasicBlockRef llvm_end_block;
|
||||
|
||||
/* WASM operation stack */
|
||||
AOTValueStack value_stack;
|
||||
/* WASM operation stack */
|
||||
AOTValueStack value_stack;
|
||||
|
||||
/* Param count/types/PHIs of this block */
|
||||
uint32 param_count;
|
||||
uint8 *param_types;
|
||||
LLVMValueRef *param_phis;
|
||||
LLVMValueRef *else_param_phis;
|
||||
/* Param count/types/PHIs of this block */
|
||||
uint32 param_count;
|
||||
uint8 *param_types;
|
||||
LLVMValueRef *param_phis;
|
||||
LLVMValueRef *else_param_phis;
|
||||
|
||||
/* Result count/types/PHIs of this block */
|
||||
uint32 result_count;
|
||||
uint8 *result_types;
|
||||
LLVMValueRef *result_phis;
|
||||
/* Result count/types/PHIs of this block */
|
||||
uint32 result_count;
|
||||
uint8 *result_types;
|
||||
LLVMValueRef *result_phis;
|
||||
} AOTBlock;
|
||||
|
||||
/**
|
||||
* Block stack, represents WASM block stack elements
|
||||
*/
|
||||
typedef struct AOTBlockStack {
|
||||
AOTBlock *block_list_head;
|
||||
AOTBlock *block_list_end;
|
||||
/* Current block index of each block type */
|
||||
uint32 block_index[3];
|
||||
AOTBlock *block_list_head;
|
||||
AOTBlock *block_list_end;
|
||||
/* Current block index of each block type */
|
||||
uint32 block_index[3];
|
||||
} AOTBlockStack;
|
||||
|
||||
typedef struct AOTCheckedAddr {
|
||||
struct AOTCheckedAddr *next;
|
||||
uint32 local_idx;
|
||||
uint32 offset;
|
||||
uint32 bytes;
|
||||
struct AOTCheckedAddr *next;
|
||||
uint32 local_idx;
|
||||
uint32 offset;
|
||||
uint32 bytes;
|
||||
} AOTCheckedAddr, *AOTCheckedAddrList;
|
||||
|
||||
typedef struct AOTMemInfo {
|
||||
LLVMValueRef mem_base_addr;
|
||||
LLVMValueRef mem_data_size_addr;
|
||||
LLVMValueRef mem_cur_page_count_addr;
|
||||
LLVMValueRef mem_bound_check_1byte;
|
||||
LLVMValueRef mem_bound_check_2bytes;
|
||||
LLVMValueRef mem_bound_check_4bytes;
|
||||
LLVMValueRef mem_bound_check_8bytes;
|
||||
LLVMValueRef mem_bound_check_16bytes;
|
||||
LLVMValueRef mem_base_addr;
|
||||
LLVMValueRef mem_data_size_addr;
|
||||
LLVMValueRef mem_cur_page_count_addr;
|
||||
LLVMValueRef mem_bound_check_1byte;
|
||||
LLVMValueRef mem_bound_check_2bytes;
|
||||
LLVMValueRef mem_bound_check_4bytes;
|
||||
LLVMValueRef mem_bound_check_8bytes;
|
||||
LLVMValueRef mem_bound_check_16bytes;
|
||||
} AOTMemInfo;
|
||||
|
||||
typedef struct AOTFuncContext {
|
||||
AOTFunc *aot_func;
|
||||
LLVMValueRef func;
|
||||
LLVMTypeRef func_type;
|
||||
AOTBlockStack block_stack;
|
||||
AOTFunc *aot_func;
|
||||
LLVMValueRef func;
|
||||
LLVMTypeRef func_type;
|
||||
AOTBlockStack block_stack;
|
||||
|
||||
LLVMValueRef exec_env;
|
||||
LLVMValueRef aot_inst;
|
||||
LLVMValueRef argv_buf;
|
||||
LLVMValueRef native_stack_bound;
|
||||
LLVMValueRef aux_stack_bound;
|
||||
LLVMValueRef aux_stack_bottom;
|
||||
LLVMValueRef native_symbol;
|
||||
LLVMValueRef last_alloca;
|
||||
LLVMValueRef func_ptrs;
|
||||
LLVMValueRef exec_env;
|
||||
LLVMValueRef aot_inst;
|
||||
LLVMValueRef argv_buf;
|
||||
LLVMValueRef native_stack_bound;
|
||||
LLVMValueRef aux_stack_bound;
|
||||
LLVMValueRef aux_stack_bottom;
|
||||
LLVMValueRef native_symbol;
|
||||
LLVMValueRef last_alloca;
|
||||
LLVMValueRef func_ptrs;
|
||||
|
||||
AOTMemInfo *mem_info;
|
||||
AOTMemInfo *mem_info;
|
||||
|
||||
LLVMValueRef cur_exception;
|
||||
LLVMValueRef cur_exception;
|
||||
|
||||
bool mem_space_unchanged;
|
||||
AOTCheckedAddrList checked_addr_list;
|
||||
bool mem_space_unchanged;
|
||||
AOTCheckedAddrList checked_addr_list;
|
||||
|
||||
LLVMBasicBlockRef got_exception_block;
|
||||
LLVMBasicBlockRef func_return_block;
|
||||
LLVMValueRef exception_id_phi;
|
||||
LLVMValueRef func_type_indexes;
|
||||
LLVMBasicBlockRef got_exception_block;
|
||||
LLVMBasicBlockRef func_return_block;
|
||||
LLVMValueRef exception_id_phi;
|
||||
LLVMValueRef func_type_indexes;
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
LLVMMetadataRef debug_func;
|
||||
LLVMMetadataRef debug_func;
|
||||
#endif
|
||||
LLVMValueRef locals[1];
|
||||
LLVMValueRef locals[1];
|
||||
} AOTFuncContext;
|
||||
|
||||
typedef struct AOTLLVMTypes {
|
||||
LLVMTypeRef int1_type;
|
||||
LLVMTypeRef int8_type;
|
||||
LLVMTypeRef int16_type;
|
||||
LLVMTypeRef int32_type;
|
||||
LLVMTypeRef int64_type;
|
||||
LLVMTypeRef float32_type;
|
||||
LLVMTypeRef float64_type;
|
||||
LLVMTypeRef void_type;
|
||||
LLVMTypeRef int1_type;
|
||||
LLVMTypeRef int8_type;
|
||||
LLVMTypeRef int16_type;
|
||||
LLVMTypeRef int32_type;
|
||||
LLVMTypeRef int64_type;
|
||||
LLVMTypeRef float32_type;
|
||||
LLVMTypeRef float64_type;
|
||||
LLVMTypeRef void_type;
|
||||
|
||||
LLVMTypeRef int8_ptr_type;
|
||||
LLVMTypeRef int8_pptr_type;
|
||||
LLVMTypeRef int16_ptr_type;
|
||||
LLVMTypeRef int32_ptr_type;
|
||||
LLVMTypeRef int64_ptr_type;
|
||||
LLVMTypeRef float32_ptr_type;
|
||||
LLVMTypeRef float64_ptr_type;
|
||||
LLVMTypeRef int8_ptr_type;
|
||||
LLVMTypeRef int8_pptr_type;
|
||||
LLVMTypeRef int16_ptr_type;
|
||||
LLVMTypeRef int32_ptr_type;
|
||||
LLVMTypeRef int64_ptr_type;
|
||||
LLVMTypeRef float32_ptr_type;
|
||||
LLVMTypeRef float64_ptr_type;
|
||||
|
||||
LLVMTypeRef v128_type;
|
||||
LLVMTypeRef v128_ptr_type;
|
||||
LLVMTypeRef i8x16_vec_type;
|
||||
LLVMTypeRef i16x8_vec_type;
|
||||
LLVMTypeRef i32x4_vec_type;
|
||||
LLVMTypeRef i64x2_vec_type;
|
||||
LLVMTypeRef f32x4_vec_type;
|
||||
LLVMTypeRef f64x2_vec_type;
|
||||
LLVMTypeRef v128_type;
|
||||
LLVMTypeRef v128_ptr_type;
|
||||
LLVMTypeRef i8x16_vec_type;
|
||||
LLVMTypeRef i16x8_vec_type;
|
||||
LLVMTypeRef i32x4_vec_type;
|
||||
LLVMTypeRef i64x2_vec_type;
|
||||
LLVMTypeRef f32x4_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 externref_type;
|
||||
LLVMTypeRef funcref_type;
|
||||
LLVMTypeRef externref_type;
|
||||
} AOTLLVMTypes;
|
||||
|
||||
typedef struct AOTLLVMConsts {
|
||||
|
@ -245,89 +244,89 @@ typedef struct AOTLLVMConsts {
|
|||
* Compiler context
|
||||
*/
|
||||
typedef struct AOTCompContext {
|
||||
AOTCompData *comp_data;
|
||||
AOTCompData *comp_data;
|
||||
|
||||
/* LLVM variables required to emit LLVM IR */
|
||||
LLVMContextRef context;
|
||||
LLVMModuleRef module;
|
||||
LLVMBuilderRef builder;
|
||||
/* LLVM variables required to emit LLVM IR */
|
||||
LLVMContextRef context;
|
||||
LLVMModuleRef module;
|
||||
LLVMBuilderRef builder;
|
||||
#if WASM_ENABLE_DEBUG_AOT
|
||||
LLVMDIBuilderRef debug_builder;
|
||||
LLVMMetadataRef debug_file;
|
||||
LLVMMetadataRef debug_comp_unit;
|
||||
LLVMDIBuilderRef debug_builder;
|
||||
LLVMMetadataRef debug_file;
|
||||
LLVMMetadataRef debug_comp_unit;
|
||||
#endif
|
||||
LLVMTargetMachineRef target_machine;
|
||||
char *target_cpu;
|
||||
char target_arch[16];
|
||||
unsigned pointer_size;
|
||||
LLVMTargetMachineRef target_machine;
|
||||
char *target_cpu;
|
||||
char target_arch[16];
|
||||
unsigned pointer_size;
|
||||
|
||||
/* Hardware intrinsic compability flags */
|
||||
uint64 flags[8];
|
||||
/* Hardware intrinsic compability flags */
|
||||
uint64 flags[8];
|
||||
|
||||
/* LLVM execution engine required by JIT */
|
||||
/* LLVM execution engine required by JIT */
|
||||
#if WASM_ENABLE_LAZY_JIT != 0
|
||||
LLVMOrcLLLazyJITRef lazy_orcjit;
|
||||
LLVMOrcThreadSafeContextRef ts_context;
|
||||
LLVMOrcJITTargetMachineBuilderRef tm_builder;
|
||||
LLVMOrcLLLazyJITRef lazy_orcjit;
|
||||
LLVMOrcThreadSafeContextRef ts_context;
|
||||
LLVMOrcJITTargetMachineBuilderRef tm_builder;
|
||||
#else
|
||||
LLVMExecutionEngineRef exec_engine;
|
||||
LLVMExecutionEngineRef exec_engine;
|
||||
#endif
|
||||
bool is_jit_mode;
|
||||
bool is_jit_mode;
|
||||
|
||||
/* AOT indirect mode flag & symbol list */
|
||||
bool is_indirect_mode;
|
||||
bh_list native_symbols;
|
||||
/* AOT indirect mode flag & symbol list */
|
||||
bool is_indirect_mode;
|
||||
bh_list native_symbols;
|
||||
|
||||
/* Bulk memory feature */
|
||||
bool enable_bulk_memory;
|
||||
/* Bulk memory feature */
|
||||
bool enable_bulk_memory;
|
||||
|
||||
/* Bounday Check */
|
||||
bool enable_bound_check;
|
||||
/* Bounday Check */
|
||||
bool enable_bound_check;
|
||||
|
||||
/* 128-bit SIMD */
|
||||
bool enable_simd;
|
||||
/* 128-bit SIMD */
|
||||
bool enable_simd;
|
||||
|
||||
/* Auxiliary stack overflow/underflow check */
|
||||
bool enable_aux_stack_check;
|
||||
/* Auxiliary stack overflow/underflow check */
|
||||
bool enable_aux_stack_check;
|
||||
|
||||
/* Generate auxiliary stack frame */
|
||||
bool enable_aux_stack_frame;
|
||||
/* Generate auxiliary stack frame */
|
||||
bool enable_aux_stack_frame;
|
||||
|
||||
/* Thread Manager */
|
||||
bool enable_thread_mgr;
|
||||
/* Thread Manager */
|
||||
bool enable_thread_mgr;
|
||||
|
||||
/* Tail Call */
|
||||
bool enable_tail_call;
|
||||
/* Tail Call */
|
||||
bool enable_tail_call;
|
||||
|
||||
/* Reference Types */
|
||||
bool enable_ref_types;
|
||||
/* Reference Types */
|
||||
bool enable_ref_types;
|
||||
|
||||
/* Disable LLVM built-in intrinsics */
|
||||
bool disable_llvm_intrinsics;
|
||||
/* Disable LLVM built-in intrinsics */
|
||||
bool disable_llvm_intrinsics;
|
||||
|
||||
/* Whether optimize the JITed code */
|
||||
bool optimize;
|
||||
/* Whether optimize the JITed code */
|
||||
bool optimize;
|
||||
|
||||
/* LLVM pass manager to optimize the JITed code */
|
||||
LLVMPassManagerRef pass_mgr;
|
||||
/* LLVM pass manager to optimize the JITed code */
|
||||
LLVMPassManagerRef pass_mgr;
|
||||
|
||||
/* LLVM floating-point rounding mode metadata */
|
||||
LLVMValueRef fp_rounding_mode;
|
||||
/* LLVM floating-point rounding mode metadata */
|
||||
LLVMValueRef fp_rounding_mode;
|
||||
|
||||
/* LLVM floating-point exception behavior metadata */
|
||||
LLVMValueRef fp_exception_behavior;
|
||||
/* LLVM floating-point exception behavior metadata */
|
||||
LLVMValueRef fp_exception_behavior;
|
||||
|
||||
/* LLVM data types */
|
||||
AOTLLVMTypes basic_types;
|
||||
LLVMTypeRef exec_env_type;
|
||||
LLVMTypeRef aot_inst_type;
|
||||
/* LLVM data types */
|
||||
AOTLLVMTypes basic_types;
|
||||
LLVMTypeRef exec_env_type;
|
||||
LLVMTypeRef aot_inst_type;
|
||||
|
||||
/* LLVM const values */
|
||||
AOTLLVMConsts llvm_consts;
|
||||
/* LLVM const values */
|
||||
AOTLLVMConsts llvm_consts;
|
||||
|
||||
/* Function contexts */
|
||||
AOTFuncContext **func_ctxes;
|
||||
uint32 func_ctx_count;
|
||||
/* Function contexts */
|
||||
AOTFuncContext **func_ctxes;
|
||||
uint32 func_ctx_count;
|
||||
} AOTCompContext;
|
||||
|
||||
enum {
|
||||
|
@ -337,7 +336,7 @@ enum {
|
|||
AOT_LLVMIR_OPT_FILE,
|
||||
};
|
||||
|
||||
typedef struct AOTCompOption{
|
||||
typedef struct AOTCompOption {
|
||||
bool is_jit_mode;
|
||||
bool is_indirect_mode;
|
||||
char *target_arch;
|
||||
|
@ -360,8 +359,7 @@ typedef struct AOTCompOption{
|
|||
} AOTCompOption, *aot_comp_option_t;
|
||||
|
||||
AOTCompContext *
|
||||
aot_create_comp_context(AOTCompData *comp_data,
|
||||
aot_comp_option_t option);
|
||||
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
|
||||
|
||||
void
|
||||
aot_destroy_comp_context(AOTCompContext *comp_ctx);
|
||||
|
@ -372,7 +370,7 @@ aot_get_native_symbol_index(AOTCompContext *comp_ctx, const char *symbol);
|
|||
bool
|
||||
aot_compile_wasm(AOTCompContext *comp_ctx);
|
||||
|
||||
uint8*
|
||||
uint8 *
|
||||
aot_emit_elf_file(AOTCompContext *comp_ctx, uint32 *p_elf_file_size);
|
||||
|
||||
void
|
||||
|
@ -403,57 +401,46 @@ LLVMTypeRef
|
|||
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
|
||||
|
||||
bool
|
||||
aot_checked_addr_list_add(AOTFuncContext *func_ctx,
|
||||
uint32 local_idx, uint32 offset, uint32 bytes);
|
||||
aot_checked_addr_list_add(AOTFuncContext *func_ctx, uint32 local_idx,
|
||||
uint32 offset, uint32 bytes);
|
||||
|
||||
void
|
||||
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
|
||||
|
||||
bool
|
||||
aot_checked_addr_list_find(AOTFuncContext *func_ctx,
|
||||
uint32 local_idx, uint32 offset, uint32 bytes);
|
||||
aot_checked_addr_list_find(AOTFuncContext *func_ctx, uint32 local_idx,
|
||||
uint32 offset, uint32 bytes);
|
||||
|
||||
void
|
||||
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_build_zero_function_ret(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_build_zero_function_ret(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
AOTFuncType *func_type);
|
||||
|
||||
LLVMValueRef
|
||||
aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
const char *intrinsic,
|
||||
LLVMTypeRef ret_type,
|
||||
LLVMTypeRef *param_types,
|
||||
int param_count,
|
||||
...);
|
||||
const AOTFuncContext *func_ctx, const char *intrinsic,
|
||||
LLVMTypeRef ret_type, LLVMTypeRef *param_types,
|
||||
int param_count, ...);
|
||||
|
||||
LLVMValueRef
|
||||
aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
const char *intrinsic,
|
||||
LLVMTypeRef ret_type,
|
||||
LLVMTypeRef *param_types,
|
||||
int param_count,
|
||||
va_list param_value_list);
|
||||
const AOTFuncContext *func_ctx, const char *intrinsic,
|
||||
LLVMTypeRef ret_type, LLVMTypeRef *param_types,
|
||||
int param_count, va_list param_value_list);
|
||||
|
||||
LLVMValueRef
|
||||
aot_get_func_from_table(const AOTCompContext *comp_ctx,
|
||||
LLVMValueRef base,
|
||||
LLVMTypeRef func_type,
|
||||
int32 index);
|
||||
aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
|
||||
LLVMTypeRef func_type, int32 index);
|
||||
|
||||
bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
|
||||
|
||||
#if WASM_ENABLE_LAZY_JIT != 0
|
||||
void
|
||||
aot_handle_llvm_errmsg(char *error_buf,
|
||||
uint32 error_buf_size,
|
||||
const char *string,
|
||||
LLVMErrorRef error);
|
||||
aot_handle_llvm_errmsg(char *error_buf, uint32 error_buf_size,
|
||||
const char *string, LLVMErrorRef error);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -461,4 +448,3 @@ aot_handle_llvm_errmsg(char *error_buf,
|
|||
#endif
|
||||
|
||||
#endif /* end of _AOT_LLVM_H_ */
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@ extern "C" LLVMBool
|
|||
WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleRef M,
|
||||
LLVMMCJITCompilerOptions *PassedOptions,
|
||||
size_t SizeOfPassedOptions,
|
||||
char **OutError);
|
||||
size_t SizeOfPassedOptions, char **OutError);
|
||||
|
||||
extern "C" bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
|
||||
|
@ -38,23 +37,21 @@ LLVMBool
|
|||
WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleRef M,
|
||||
LLVMMCJITCompilerOptions *PassedOptions,
|
||||
size_t SizeOfPassedOptions,
|
||||
char **OutError)
|
||||
size_t SizeOfPassedOptions, char **OutError)
|
||||
{
|
||||
LLVMMCJITCompilerOptions options;
|
||||
// If the user passed a larger sized options struct, then they were compiled
|
||||
// against a newer LLVM. Tell them that something is wrong.
|
||||
if (SizeOfPassedOptions > sizeof(options)) {
|
||||
*OutError = strdup(
|
||||
"Refusing to use options struct that is larger than my own; assuming "
|
||||
"LLVM library mismatch.");
|
||||
*OutError = strdup("Refusing to use options struct that is larger than "
|
||||
"my own; assuming LLVM library mismatch.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 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
|
||||
// set to the bitwise equivalent of zero, and assume that this means "do the
|
||||
// default" as if that option hadn't been available.
|
||||
// any fields they didn't see are cleared. We must defend against fields
|
||||
// being set to the bitwise equivalent of zero, and assume that this means
|
||||
// "do the default" as if that option hadn't been available.
|
||||
LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
|
||||
memcpy(&options, PassedOptions, SizeOfPassedOptions);
|
||||
|
||||
|
@ -68,8 +65,9 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
|||
for (auto &F : *Mod) {
|
||||
auto Attrs = F.getAttributes();
|
||||
StringRef Value = options.NoFramePointerElim ? "all" : "none";
|
||||
Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
|
||||
"frame-pointer", Value);
|
||||
Attrs =
|
||||
Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
|
||||
"frame-pointer", Value);
|
||||
F.setAttributes(Attrs);
|
||||
}
|
||||
}
|
||||
|
@ -88,15 +86,15 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
|||
|
||||
EngineBuilder builder(std::move(Mod));
|
||||
builder.setEngineKind(EngineKind::JIT)
|
||||
.setErrorStr(&Error)
|
||||
.setMCPU(mcpu)
|
||||
.setOptLevel((CodeGenOpt::Level)options.OptLevel)
|
||||
.setTargetOptions(targetOptions);
|
||||
.setErrorStr(&Error)
|
||||
.setMCPU(mcpu)
|
||||
.setOptLevel((CodeGenOpt::Level)options.OptLevel)
|
||||
.setTargetOptions(targetOptions);
|
||||
if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
|
||||
builder.setCodeModel(*CM);
|
||||
if (options.MCJMM)
|
||||
builder.setMCJITMemoryManager(
|
||||
std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
|
||||
std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
|
||||
if (ExecutionEngine *JIT = builder.create()) {
|
||||
*OutJIT = wrap(JIT);
|
||||
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::Triple targetTriple(arch_c_str, "", "");
|
||||
auto targetMachine =
|
||||
std::unique_ptr<llvm::TargetMachine>(llvm::EngineBuilder().selectTarget(
|
||||
targetTriple, "", std::string(cpu_c_str), targetAttributes));
|
||||
std::unique_ptr<llvm::TargetMachine>(llvm::EngineBuilder().selectTarget(
|
||||
targetTriple, "", std::string(cpu_c_str), targetAttributes));
|
||||
if (!targetMachine) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const llvm::Triple::ArchType targetArch =
|
||||
targetMachine->getTargetTriple().getArch();
|
||||
targetMachine->getTargetTriple().getArch();
|
||||
const llvm::MCSubtargetInfo *subTargetInfo =
|
||||
targetMachine->getMCSubtargetInfo();
|
||||
targetMachine->getMCSubtargetInfo();
|
||||
if (subTargetInfo == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -145,4 +143,3 @@ aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
|
|||
return true;
|
||||
#endif /* WASM_ENABLE_SIMD */
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ void
|
|||
LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
|
||||
LLVMOrcLLJITBuilderRef Builder);
|
||||
LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, LLVMOrcLLJITBuilderRef Builder);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
|
||||
|
@ -31,13 +30,11 @@ char
|
|||
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
|
||||
LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcThreadSafeModuleRef TSM);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
|
||||
LLVMOrcJITTargetAddress *Result,
|
||||
LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, LLVMOrcJITTargetAddress *Result,
|
||||
const char *Name);
|
||||
|
||||
const char *
|
||||
|
@ -45,8 +42,7 @@ LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
|
|||
|
||||
void
|
||||
LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
|
||||
LLVMOrcLLJITBuilderRef Builder,
|
||||
LLVMOrcJITTargetMachineBuilderRef JTMB);
|
||||
LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
|
||||
|
||||
char
|
||||
LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
|
||||
|
@ -91,16 +87,14 @@ LLVMOrcDisposeLLLazyJIT(LLVMOrcLLLazyJITRef J)
|
|||
}
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J,
|
||||
LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcThreadSafeModuleRef TSM)
|
||||
{
|
||||
return LLVMOrcLLJITAddLLVMIRModule(J, JD, TSM);
|
||||
}
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J,
|
||||
LLVMOrcJITTargetAddress *Result,
|
||||
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcJITTargetAddress *Result,
|
||||
const char *Name)
|
||||
{
|
||||
return LLVMOrcLLJITLookup(J, Result, Name);
|
||||
|
@ -114,8 +108,7 @@ LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J)
|
|||
|
||||
void
|
||||
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
|
||||
LLVMOrcLLLazyJITBuilderRef Builder,
|
||||
LLVMOrcJITTargetMachineBuilderRef JTMB)
|
||||
LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB)
|
||||
{
|
||||
return LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);
|
||||
}
|
||||
|
@ -125,4 +118,3 @@ LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J)
|
|||
{
|
||||
return LLVMOrcLLJITGetGlobalPrefix(J);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "llvm-c/LLJIT.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -49,13 +48,11 @@ char
|
|||
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J,
|
||||
LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcJITDylibRef JD,
|
||||
LLVMOrcThreadSafeModuleRef TSM);
|
||||
|
||||
LLVMErrorRef
|
||||
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J,
|
||||
LLVMOrcJITTargetAddress *Result,
|
||||
LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcJITTargetAddress *Result,
|
||||
const char *Name);
|
||||
|
||||
const char *
|
||||
|
@ -63,8 +60,7 @@ LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J);
|
|||
|
||||
void
|
||||
LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
|
||||
LLVMOrcLLLazyJITBuilderRef Builder,
|
||||
LLVMOrcJITTargetMachineBuilderRef JTMB);
|
||||
LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
|
||||
|
||||
char
|
||||
LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
|
||||
|
@ -74,4 +70,3 @@ LLVMOrcLLLazyJITGetGlobalPrefix(LLVMOrcLLLazyJITRef J);
|
|||
#endif
|
||||
|
||||
#endif /* end of AOT_LLVM_LAZYJIT_H */
|
||||
|
||||
|
|
|
@ -28,31 +28,30 @@
|
|||
|
||||
using namespace lldb;
|
||||
|
||||
typedef struct dwar_extractor
|
||||
{
|
||||
typedef struct dwar_extractor {
|
||||
SBDebugger debugger;
|
||||
SBTarget target;
|
||||
SBModule module;
|
||||
|
||||
} 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;
|
||||
|
||||
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 *platform = NULL;
|
||||
dwar_extractor * extractor = NULL;
|
||||
dwar_extractor *extractor = NULL;
|
||||
|
||||
//__attribute__((constructor)) may be better?
|
||||
if (!is_debugger_initialized) {
|
||||
SBError error = SBDebugger::InitializeWithErrorHandling();
|
||||
if(error.Fail()) {
|
||||
if (error.Fail()) {
|
||||
LOG_ERROR("Init Dwarf Debugger failed");
|
||||
return TO_HANDLE(NULL);
|
||||
}
|
||||
|
@ -62,7 +61,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char * file_name)
|
|||
SBError error;
|
||||
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");
|
||||
goto fail3;
|
||||
}
|
||||
|
@ -74,7 +73,7 @@ create_dwarf_extractor(AOTCompData *comp_data, char * file_name)
|
|||
}
|
||||
|
||||
extractor->target = extractor->debugger.CreateTarget(
|
||||
file_name, arch, platform, false, error);
|
||||
file_name, arch, platform, false, error);
|
||||
|
||||
if (!error.Success()) {
|
||||
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);
|
||||
comp_data->extractor = TO_HANDLE(extractor);
|
||||
|
||||
return TO_HANDLE(extractor);
|
||||
return TO_HANDLE(extractor);
|
||||
|
||||
fail1:
|
||||
SBDebugger::Destroy(extractor->debugger);
|
||||
|
@ -104,7 +103,7 @@ fail3:
|
|||
void
|
||||
destroy_dwarf_extractor(dwar_extractor_handle_t handle)
|
||||
{
|
||||
dwar_extractor * extractor = TO_EXTACTOR(handle);
|
||||
dwar_extractor *extractor = TO_EXTACTOR(handle);
|
||||
if (!extractor)
|
||||
return;
|
||||
extractor->debugger.DeleteTarget(extractor->target);
|
||||
|
@ -129,8 +128,7 @@ dwarf_gen_file_info(AOTCompContext *comp_ctx)
|
|||
units_number = extractor->module.GetNumCompileUnits();
|
||||
|
||||
if (units_number > 0) {
|
||||
SBCompileUnit compile_unit =
|
||||
extractor->module.GetCompileUnitAtIndex(0);
|
||||
SBCompileUnit compile_unit = extractor->module.GetCompileUnitAtIndex(0);
|
||||
auto filespec = compile_unit.GetFileSpec();
|
||||
file_name = filespec.GetFilename();
|
||||
dir_name = filespec.GetDirectory();
|
||||
|
@ -205,30 +203,26 @@ dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx)
|
|||
units_number = extractor->module.GetNumCompileUnits();
|
||||
|
||||
if (units_number > 0) {
|
||||
SBCompileUnit compile_unit =
|
||||
extractor->module.GetCompileUnitAtIndex(0);
|
||||
SBCompileUnit compile_unit = extractor->module.GetCompileUnitAtIndex(0);
|
||||
auto lang_type = compile_unit.GetLanguage();
|
||||
|
||||
comp_unit = LLVMDIBuilderCreateCompileUnit(
|
||||
comp_ctx->debug_builder, LLDB_TO_LLVM_LANG_TYPE(lang_type),
|
||||
comp_ctx->debug_file, "ant compiler", 12, 0, NULL, 0, 1, NULL, 0,
|
||||
LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
|
||||
comp_ctx->debug_builder, LLDB_TO_LLVM_LANG_TYPE(lang_type),
|
||||
comp_ctx->debug_file, "ant compiler", 12, 0, NULL, 0, 1, NULL, 0,
|
||||
LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
|
||||
}
|
||||
return comp_unit;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset)
|
||||
{
|
||||
dwar_extractor *extractor = TO_EXTACTOR(handle);
|
||||
auto sbaddr = extractor->target.ResolveFileAddress(offset);
|
||||
SBSymbolContext sc(
|
||||
sbaddr.GetSymbolContext(eSymbolContextFunction));
|
||||
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction));
|
||||
if (sc.IsValid()) {
|
||||
SBFunction function(sc.GetFunction());
|
||||
if (function.IsValid()) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,42 +230,41 @@ dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset)
|
|||
static LLVMDWARFTypeEncoding
|
||||
lldb_get_basic_type_encoding(BasicType basic_type)
|
||||
{
|
||||
LLVMDWARFTypeEncoding encoding = 0;
|
||||
switch (basic_type)
|
||||
{
|
||||
case eBasicTypeUnsignedChar:
|
||||
encoding = llvm::dwarf::DW_ATE_unsigned_char;
|
||||
break;
|
||||
case eBasicTypeSignedChar:
|
||||
encoding = llvm::dwarf::DW_ATE_signed_char;
|
||||
break;
|
||||
case eBasicTypeUnsignedInt:
|
||||
case eBasicTypeUnsignedLong:
|
||||
case eBasicTypeUnsignedLongLong:
|
||||
case eBasicTypeUnsignedWChar:
|
||||
case eBasicTypeUnsignedInt128:
|
||||
case eBasicTypeUnsignedShort:
|
||||
encoding = llvm::dwarf::DW_ATE_unsigned;
|
||||
break;
|
||||
case eBasicTypeInt:
|
||||
case eBasicTypeLong:
|
||||
case eBasicTypeLongLong:
|
||||
case eBasicTypeWChar:
|
||||
case eBasicTypeInt128:
|
||||
case eBasicTypeShort:
|
||||
encoding = llvm::dwarf::DW_ATE_signed;
|
||||
break;
|
||||
case eBasicTypeBool:
|
||||
encoding = llvm::dwarf::DW_ATE_boolean;
|
||||
break;
|
||||
case eBasicTypeHalf:
|
||||
case eBasicTypeFloat:
|
||||
case eBasicTypeDouble:
|
||||
case eBasicTypeLongDouble:
|
||||
encoding = llvm::dwarf::DW_ATE_float;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
LLVMDWARFTypeEncoding encoding = 0;
|
||||
switch (basic_type) {
|
||||
case eBasicTypeUnsignedChar:
|
||||
encoding = llvm::dwarf::DW_ATE_unsigned_char;
|
||||
break;
|
||||
case eBasicTypeSignedChar:
|
||||
encoding = llvm::dwarf::DW_ATE_signed_char;
|
||||
break;
|
||||
case eBasicTypeUnsignedInt:
|
||||
case eBasicTypeUnsignedLong:
|
||||
case eBasicTypeUnsignedLongLong:
|
||||
case eBasicTypeUnsignedWChar:
|
||||
case eBasicTypeUnsignedInt128:
|
||||
case eBasicTypeUnsignedShort:
|
||||
encoding = llvm::dwarf::DW_ATE_unsigned;
|
||||
break;
|
||||
case eBasicTypeInt:
|
||||
case eBasicTypeLong:
|
||||
case eBasicTypeLongLong:
|
||||
case eBasicTypeWChar:
|
||||
case eBasicTypeInt128:
|
||||
case eBasicTypeShort:
|
||||
encoding = llvm::dwarf::DW_ATE_signed;
|
||||
break;
|
||||
case eBasicTypeBool:
|
||||
encoding = llvm::dwarf::DW_ATE_boolean;
|
||||
break;
|
||||
case eBasicTypeHalf:
|
||||
case eBasicTypeFloat:
|
||||
case eBasicTypeDouble:
|
||||
case eBasicTypeLongDouble:
|
||||
encoding = llvm::dwarf::DW_ATE_float;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
@ -288,21 +281,22 @@ lldb_type_to_type_dbi(AOTCompContext *comp_ctx, SBType &type)
|
|||
if (basic_type != eBasicTypeInvalid) {
|
||||
encoding = lldb_get_basic_type_encoding(basic_type);
|
||||
type_info = LLVMDIBuilderCreateBasicType(
|
||||
DIB, type.GetName(), strlen(type.GetName()), bit_size, encoding,
|
||||
LLVMDIFlagZero);
|
||||
DIB, type.GetName(), strlen(type.GetName()), bit_size, encoding,
|
||||
LLVMDIFlagZero);
|
||||
}
|
||||
else if (type.IsPointerType()) {
|
||||
SBType pointee_type = type.GetPointeeType();
|
||||
type_info = LLVMDIBuilderCreatePointerType(
|
||||
DIB, lldb_type_to_type_dbi(comp_ctx, pointee_type), bit_size, 0, 0,
|
||||
"", 0);
|
||||
DIB, lldb_type_to_type_dbi(comp_ctx, pointee_type), bit_size, 0, 0,
|
||||
"", 0);
|
||||
}
|
||||
|
||||
return type_info;
|
||||
}
|
||||
|
||||
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());
|
||||
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)))
|
||||
return NULL;
|
||||
|
||||
|
||||
|
||||
LLVMDIBuilderRef DIB = comp_ctx->debug_builder;
|
||||
LLVMMetadataRef File = comp_ctx->debug_file;
|
||||
|
||||
LLVMMetadataRef ParamTypes[num_function_args + 1];
|
||||
|
||||
|
||||
ParamTypes[0] = lldb_type_to_type_dbi(comp_ctx, return_type);
|
||||
|
||||
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);
|
||||
|
||||
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 =
|
||||
LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, num_function_args + 1, LLVMDIFlagZero);
|
||||
|
||||
LLVMMetadataRef FunctionTy = LLVMDIBuilderCreateSubroutineType(
|
||||
DIB, File, ParamTypes, num_function_args + 1, LLVMDIFlagZero);
|
||||
|
||||
auto line_entry = sc.GetLineEntry();
|
||||
LLVMMetadataRef ReplaceableFunctionMetadata =
|
||||
LLVMDIBuilderCreateReplaceableCompositeType(
|
||||
DIB, 0x15, function_name, strlen(function_name), File, File,
|
||||
line_entry.GetLine(), 0, 0, 0, LLVMDIFlagFwdDecl, "", 0);
|
||||
LLVMDIBuilderCreateReplaceableCompositeType(
|
||||
DIB, 0x15, function_name, strlen(function_name), File, File,
|
||||
line_entry.GetLine(), 0, 0, 0, LLVMDIFlagFwdDecl, "", 0);
|
||||
|
||||
LLVMMetadataRef FunctionMetadata =
|
||||
LLVMDIBuilderCreateFunction(DIB, File, function_name, strlen(function_name), link_name, strlen(link_name),
|
||||
File, line_entry.GetLine(), FunctionTy, true, true, line_entry.GetLine(), LLVMDIFlagZero, false);
|
||||
|
||||
LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
|
||||
LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction(
|
||||
DIB, File, function_name, strlen(function_name), link_name,
|
||||
strlen(link_name), File, line_entry.GetLine(), FunctionTy, true, true,
|
||||
line_entry.GetLine(), LLVMDIFlagZero, false);
|
||||
|
||||
LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata,
|
||||
FunctionMetadata);
|
||||
|
||||
LLVMSetSubprogram(func_ctx->func, FunctionMetadata);
|
||||
|
||||
LLVMMetadataRef ParamExpression = LLVMDIBuilderCreateExpression(DIB, NULL, 0);
|
||||
auto variable_list = function.GetBlock().GetVariables(extractor->target, true, false,false);
|
||||
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 ParamExpression =
|
||||
LLVMDIBuilderCreateExpression(DIB, NULL, 0);
|
||||
auto variable_list =
|
||||
function.GetBlock().GetVariables(extractor->target, true, false, false);
|
||||
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(
|
||||
comp_ctx->context, line_entry.GetLine(), 0, FunctionMetadata, NULL);
|
||||
|
||||
//TODO:change to void * or WasmExenv * ?
|
||||
LLVMMetadataRef voidtype = LLVMDIBuilderCreateBasicType(DIB, "void", 4, 0, 0, LLVMDIFlagZero);
|
||||
LLVMMetadataRef voidpionter = LLVMDIBuilderCreatePointerType(DIB, voidtype, 64, 0, 0, "void *", 6);
|
||||
comp_ctx->context, line_entry.GetLine(), 0, FunctionMetadata, NULL);
|
||||
|
||||
// TODO:change to void * or WasmExenv * ?
|
||||
LLVMMetadataRef voidtype =
|
||||
LLVMDIBuilderCreateBasicType(DIB, "void", 4, 0, 0, LLVMDIFlagZero);
|
||||
LLVMMetadataRef voidpionter =
|
||||
LLVMDIBuilderCreatePointerType(DIB, voidtype, 64, 0, 0, "void *", 6);
|
||||
|
||||
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
|
||||
DIB, FunctionMetadata, "exenv",
|
||||
5, 1,
|
||||
File, //starts form 1, and 1 is exenv,
|
||||
line_entry.GetLine(), voidpionter, true,
|
||||
LLVMDIFlagZero);
|
||||
LLVMValueRef Param =
|
||||
LLVMGetParam(func_ctx->func, 0);
|
||||
LLVMBasicBlockRef block_curr =
|
||||
LLVMGetEntryBasicBlock(func_ctx->func);
|
||||
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar,
|
||||
ParamExpression, ParamLocation,
|
||||
block_curr);
|
||||
DIB, FunctionMetadata, "exenv", 5, 1,
|
||||
File, // starts form 1, and 1 is exenv,
|
||||
line_entry.GetLine(), voidpionter, true, LLVMDIFlagZero);
|
||||
LLVMValueRef Param = LLVMGetParam(func_ctx->func, 0);
|
||||
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();
|
||||
++function_arg_idx) {
|
||||
for (uint32_t function_arg_idx = 0;
|
||||
function_arg_idx < variable_list.GetSize(); ++function_arg_idx) {
|
||||
SBValue variable(variable_list.GetValueAtIndex(function_arg_idx));
|
||||
if (variable.IsValid()) {
|
||||
SBDeclaration dec(variable.GetDeclaration());
|
||||
auto valtype = variable.GetType();
|
||||
LLVMMetadataRef ParamLocation = LLVMDIBuilderCreateDebugLocation(
|
||||
comp_ctx->context, dec.GetLine(), dec.GetColumn(),
|
||||
FunctionMetadata, NULL);
|
||||
comp_ctx->context, dec.GetLine(), dec.GetColumn(),
|
||||
FunctionMetadata, NULL);
|
||||
LLVMMetadataRef ParamVar = LLVMDIBuilderCreateParameterVariable(
|
||||
DIB, FunctionMetadata, variable.GetName(),
|
||||
strlen(variable.GetName()), function_arg_idx + 1 + 1,
|
||||
File, //starts form 1, and 1 is exenv,
|
||||
dec.GetLine(), ParamTypes[function_arg_idx + 1], true,
|
||||
LLVMDIFlagZero);
|
||||
DIB, FunctionMetadata, variable.GetName(),
|
||||
strlen(variable.GetName()), function_arg_idx + 1 + 1,
|
||||
File, // starts form 1, and 1 is exenv,
|
||||
dec.GetLine(), ParamTypes[function_arg_idx + 1], true,
|
||||
LLVMDIFlagZero);
|
||||
LLVMValueRef Param =
|
||||
LLVMGetParam(func_ctx->func, function_arg_idx + 1);
|
||||
LLVMGetParam(func_ctx->func, function_arg_idx + 1);
|
||||
LLVMDIBuilderInsertDbgValueAtEnd(DIB, Param, ParamVar,
|
||||
ParamExpression, ParamLocation,
|
||||
block_curr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FunctionMetadata;
|
||||
}
|
||||
|
||||
|
@ -413,7 +408,6 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
uint64_t vm_offset;
|
||||
AOTFunc *func = func_ctx->aot_func;
|
||||
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
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;
|
||||
|
||||
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
|
||||
SBSymbolContext sc(
|
||||
sbaddr.GetSymbolContext(eSymbolContextFunction | eSymbolContextLineEntry));
|
||||
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction
|
||||
| eSymbolContextLineEntry));
|
||||
if (sc.IsValid()) {
|
||||
SBFunction function(sc.GetFunction());
|
||||
if (function.IsValid()) {
|
||||
|
@ -436,10 +430,8 @@ dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
void
|
||||
dwarf_get_func_name(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
char *name,
|
||||
int len)
|
||||
dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
char *name, int len)
|
||||
{
|
||||
LLVMMetadataRef func_info = NULL;
|
||||
dwar_extractor *extractor;
|
||||
|
@ -449,7 +441,7 @@ dwarf_get_func_name(AOTCompContext *comp_ctx,
|
|||
name[0] = '\0';
|
||||
|
||||
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
|
||||
return ;
|
||||
return;
|
||||
|
||||
// A code address in DWARF for WebAssembly is the offset of an
|
||||
// instruction relative within the Code section of the WebAssembly file.
|
||||
|
@ -469,8 +461,7 @@ dwarf_get_func_name(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
LLVMMetadataRef
|
||||
dwarf_gen_location(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint64_t vm_offset)
|
||||
{
|
||||
LLVMMetadataRef location_info = NULL;
|
||||
|
@ -484,7 +475,7 @@ dwarf_gen_location(AOTCompContext *comp_ctx,
|
|||
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction
|
||||
| eSymbolContextLineEntry));
|
||||
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());
|
||||
if (function.IsValid()) {
|
||||
uint64_t start = func_ctx->aot_func->code
|
||||
|
@ -495,12 +486,13 @@ dwarf_gen_location(AOTCompContext *comp_ctx,
|
|||
if (function.GetStartAddress().GetOffset() <= start
|
||||
&& end <= function.GetEndAddress().GetOffset()) {
|
||||
auto line_entry = sc.GetLineEntry();
|
||||
location_info =
|
||||
LLVMDIBuilderCreateDebugLocation(
|
||||
location_info = LLVMDIBuilderCreateDebugLocation(
|
||||
comp_ctx->context, line_entry.GetLine(),
|
||||
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);
|
||||
} else
|
||||
// LOG_VERBOSE("Gen the location l:%d, c:%d at %lx",
|
||||
// line_entry.GetLine(), line_entry.GetColumn(), vm_offset);
|
||||
}
|
||||
else
|
||||
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.
|
||||
// For this reason Section::GetFileAddress() must return zero for the
|
||||
// Code section. (refert to ObjectFileWasm.cpp)
|
||||
vm_offset = (func->code + func->code_size -1) - comp_ctx->comp_data->wasm_module->buf_code;
|
||||
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset);
|
||||
vm_offset = (func->code + func->code_size - 1)
|
||||
- comp_ctx->comp_data->wasm_module->buf_code;
|
||||
location_info = dwarf_gen_location(comp_ctx, func_ctx, vm_offset);
|
||||
|
||||
return location_info;
|
||||
}
|
|
@ -11,8 +11,9 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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))
|
||||
|
||||
struct AOTCompData;
|
||||
|
@ -35,24 +36,21 @@ LLVMMetadataRef
|
|||
dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx);
|
||||
|
||||
LLVMMetadataRef
|
||||
dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
dwarf_gen_func_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
LLVMMetadataRef
|
||||
dwarf_gen_location(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
dwarf_gen_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint64_t vm_offset);
|
||||
|
||||
LLVMMetadataRef
|
||||
dwarf_gen_func_ret_location(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
dwarf_gen_func_ret_location(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
void
|
||||
dwarf_get_func_name(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
char *name,
|
||||
int len);
|
||||
dwarf_get_func_name(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
char *name, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
bool
|
||||
aot_compile_simd_shuffle(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_shuffle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip)
|
||||
{
|
||||
LLVMValueRef vec1, vec2, mask, result;
|
||||
|
@ -34,8 +33,8 @@ aot_compile_simd_shuffle(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
/* build a vector <16 x i32> */
|
||||
if (!(mask =
|
||||
simd_build_const_integer_vector(comp_ctx, I32_TYPE, values, 16))) {
|
||||
if (!(mask = simd_build_const_integer_vector(comp_ctx, I32_TYPE, values,
|
||||
16))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -54,8 +53,7 @@ fail:
|
|||
/*TODO: llvm.experimental.vector.*/
|
||||
/* shufflevector is not an option, since it requires *mask as a const */
|
||||
bool
|
||||
aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef vector, mask, max_lanes, condition, mask_lanes, result;
|
||||
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, ...> */
|
||||
if (!(max_lanes = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, INT8_TYPE, 16, 16))) {
|
||||
if (!(max_lanes = simd_build_splat_const_integer_vector(comp_ctx, INT8_TYPE,
|
||||
16, 16))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* if the highest bit of every i8 of mask is 1, means doesn't pick up from vector */
|
||||
/* select <16 x i1> %condition, <16 x i8> <0x80, 0x80, ...>, <16 x i8> %mask */
|
||||
/* if the highest bit of every i8 of mask is 1, means doesn't pick up
|
||||
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(
|
||||
comp_ctx, INT8_TYPE, 0x80, 16))) {
|
||||
comp_ctx, INT8_TYPE, 0x80, 16))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -89,8 +89,8 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!(mask = LLVMBuildSelect(comp_ctx->builder, condition, mask_lanes,
|
||||
mask, "mask"))) {
|
||||
if (!(mask = LLVMBuildSelect(comp_ctx->builder, condition, mask_lanes, mask,
|
||||
"mask"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSelect");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ aot_compile_simd_swizzle_x86(AOTCompContext *comp_ctx,
|
|||
param_types[0] = V128_i8x16_TYPE;
|
||||
param_types[1] = V128_i8x16_TYPE;
|
||||
if (!(result = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, "llvm.x86.ssse3.pshuf.b.128", V128_i8x16_TYPE,
|
||||
param_types, 2, vector, mask))) {
|
||||
comp_ctx, func_ctx, "llvm.x86.ssse3.pshuf.b.128", V128_i8x16_TYPE,
|
||||
param_types, 2, vector, mask))) {
|
||||
HANDLE_FAILURE("LLVMBuildCall");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
|
|||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
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;
|
||||
|
||||
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, ...> */
|
||||
if (!(max_lane_id = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, INT8_TYPE, 16, 16))) {
|
||||
comp_ctx, INT8_TYPE, 16, 16))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -152,9 +152,9 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
|
|||
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(
|
||||
comp_ctx, INT8_TYPE, 0, 16))) {
|
||||
comp_ctx, INT8_TYPE, 0, 16))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -172,8 +172,8 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(replace_with_zero =
|
||||
LLVMBuildExtractElement(comp_ctx->builder, condition,
|
||||
I8_CONST(i), "replace_with_zero"))) {
|
||||
LLVMBuildExtractElement(comp_ctx->builder, condition,
|
||||
I8_CONST(i), "replace_with_zero"))) {
|
||||
HANDLE_FAILURE("LLVMBuildExtractElement");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -185,15 +185,15 @@ aot_compile_simd_swizzle_common(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(elem_or_zero =
|
||||
LLVMBuildSelect(comp_ctx->builder, replace_with_zero,
|
||||
I8_CONST(0), elem, "elem_or_zero"))) {
|
||||
LLVMBuildSelect(comp_ctx->builder, replace_with_zero,
|
||||
I8_CONST(0), elem, "elem_or_zero"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSelect");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(undef =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef, elem_or_zero,
|
||||
I8_CONST(i), "new_vector"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef, elem_or_zero,
|
||||
I8_CONST(i), "new_vector"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -224,13 +224,9 @@ aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
static bool
|
||||
aot_compile_simd_extract(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
bool need_extend,
|
||||
bool is_signed,
|
||||
LLVMTypeRef vector_type,
|
||||
LLVMTypeRef result_type,
|
||||
aot_compile_simd_extract(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id, bool need_extend, bool is_signed,
|
||||
LLVMTypeRef vector_type, LLVMTypeRef result_type,
|
||||
unsigned aot_value_type)
|
||||
{
|
||||
LLVMValueRef vector, lane, result;
|
||||
|
@ -256,16 +252,16 @@ aot_compile_simd_extract(AOTCompContext *comp_ctx,
|
|||
if (need_extend) {
|
||||
if (is_signed) {
|
||||
/* sext <element_type> %element to <result_type> */
|
||||
if (!(result = LLVMBuildSExt(comp_ctx->builder, result,
|
||||
result_type, "ret"))) {
|
||||
if (!(result = LLVMBuildSExt(comp_ctx->builder, result, result_type,
|
||||
"ret"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSExt");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* sext <element_type> %element to <result_type> */
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result,
|
||||
result_type, "ret"))) {
|
||||
if (!(result = LLVMBuildZExt(comp_ctx->builder, result, result_type,
|
||||
"ret"))) {
|
||||
HANDLE_FAILURE("LLVMBuildZExt");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -281,8 +277,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
AOTFuncContext *func_ctx, uint8 lane_id,
|
||||
bool is_signed)
|
||||
{
|
||||
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
|
||||
aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
AOTFuncContext *func_ctx, uint8 lane_id,
|
||||
bool is_signed)
|
||||
{
|
||||
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
|
||||
aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
|
||||
V128_i32x4_TYPE, I32_TYPE, VALUE_TYPE_I32);
|
||||
|
@ -312,8 +305,7 @@ aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
|
||||
V128_i64x2_TYPE, I64_TYPE, VALUE_TYPE_I64);
|
||||
|
@ -321,8 +313,7 @@ aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
|
||||
V128_f32x4_TYPE, F32_TYPE, VALUE_TYPE_F32);
|
||||
|
@ -330,20 +321,16 @@ aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_extract(comp_ctx, func_ctx, lane_id, false, false,
|
||||
V128_f64x2_TYPE, F64_TYPE, VALUE_TYPE_F64);
|
||||
}
|
||||
|
||||
static bool
|
||||
aot_compile_simd_replace(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
unsigned new_value_type,
|
||||
LLVMTypeRef vector_type,
|
||||
bool need_reduce,
|
||||
aot_compile_simd_replace(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id, unsigned new_value_type,
|
||||
LLVMTypeRef vector_type, bool need_reduce,
|
||||
LLVMTypeRef element_type)
|
||||
{
|
||||
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,
|
||||
lane, "new_vector"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
|
@ -383,60 +371,48 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_I32, V128_i8x16_TYPE, true,
|
||||
INT8_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
|
||||
V128_i8x16_TYPE, true, INT8_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_I32, V128_i16x8_TYPE, true,
|
||||
INT16_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
|
||||
V128_i16x8_TYPE, true, INT16_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_I32, V128_i32x4_TYPE, false,
|
||||
I32_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I32,
|
||||
V128_i32x4_TYPE, false, I32_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_I64, V128_i64x2_TYPE, false,
|
||||
I64_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_I64,
|
||||
V128_i64x2_TYPE, false, I64_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_F32, V128_f32x4_TYPE, false,
|
||||
F32_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_F32,
|
||||
V128_f32x4_TYPE, false, F32_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id)
|
||||
AOTFuncContext *func_ctx, uint8 lane_id)
|
||||
{
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id,
|
||||
VALUE_TYPE_F64, V128_f64x2_TYPE, false,
|
||||
F64_TYPE);
|
||||
return aot_compile_simd_replace(comp_ctx, func_ctx, lane_id, VALUE_TYPE_F64,
|
||||
V128_f64x2_TYPE, false, F64_TYPE);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_shuffle(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_shuffle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip);
|
||||
|
||||
bool
|
||||
|
@ -22,84 +21,68 @@ aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
|
||||
bool
|
||||
aot_compile_simd_extract_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
AOTFuncContext *func_ctx, uint8 lane_id,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_extract_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id,
|
||||
AOTFuncContext *func_ctx, uint8 lane_id,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_extract_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_extract_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_extract_f32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_extract_f64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_f32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_replace_f64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
AOTFuncContext *func_ctx, uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load8_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_load8_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load16_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_load16_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load32_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_load32_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load64_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_load64_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 lane_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -16,10 +16,8 @@ enum integer_shift {
|
|||
};
|
||||
|
||||
static bool
|
||||
simd_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntShift shift_op,
|
||||
enum integer_shift itype)
|
||||
simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op, enum integer_shift itype)
|
||||
{
|
||||
LLVMValueRef vector, offset, result = NULL;
|
||||
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 };
|
||||
|
||||
LLVMValueRef undef[] = { LLVM_CONST(i8x16_undef), LLVM_CONST(i16x8_undef),
|
||||
LLVM_CONST(i32x4_undef),
|
||||
LLVM_CONST(i64x2_undef) };
|
||||
LLVM_CONST(i32x4_undef), LLVM_CONST(i64x2_undef) };
|
||||
LLVMValueRef mask[] = { LLVM_CONST(i8x16_vec_zero),
|
||||
LLVM_CONST(i16x8_vec_zero),
|
||||
LLVM_CONST(i32x4_vec_zero),
|
||||
|
@ -49,8 +46,8 @@ simd_shift(AOTCompContext *comp_ctx,
|
|||
|
||||
/* offset mod LaneBits */
|
||||
if (!lane_bits[itype]
|
||||
|| !(offset = LLVMBuildSRem(comp_ctx->builder, offset,
|
||||
lane_bits[itype], "offset_fix"))) {
|
||||
|| !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype],
|
||||
"offset_fix"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSRem");
|
||||
return false;
|
||||
}
|
||||
|
@ -72,15 +69,15 @@ simd_shift(AOTCompContext *comp_ctx,
|
|||
|
||||
/* splat to a vector */
|
||||
if (!(offset =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef[itype], offset,
|
||||
I32_ZERO, "offset_vector_base"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef[itype], offset,
|
||||
I32_ZERO, "offset_vector_base"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(offset =
|
||||
LLVMBuildShuffleVector(comp_ctx->builder, offset, undef[itype],
|
||||
mask[itype], "offset_vector"))) {
|
||||
LLVMBuildShuffleVector(comp_ctx->builder, offset, undef[itype],
|
||||
mask[itype], "offset_vector"))) {
|
||||
HANDLE_FAILURE("LLVMBuildShuffleVector");
|
||||
return false;
|
||||
}
|
||||
|
@ -119,32 +116,28 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op)
|
||||
{
|
||||
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i8x16);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op)
|
||||
{
|
||||
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i16x8);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op)
|
||||
{
|
||||
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i32x4);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op)
|
||||
{
|
||||
return simd_shift(comp_ctx, func_ctx, shift_op, e_shift_i64x2);
|
||||
|
|
|
@ -13,23 +13,19 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i8x16_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i16x8_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i32x4_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i64x2_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntShift shift_op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -47,8 +47,8 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
|
|||
|
||||
/* fill every bit in a lange with its sign bit */
|
||||
if (!(ashr_distance = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, element_type[itype], lane_bits[itype] - 1,
|
||||
lanes[itype]))) {
|
||||
comp_ctx, element_type[itype], lane_bits[itype] - 1,
|
||||
lanes[itype]))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (e_bitmask_i64x2 != itype) {
|
||||
if (!(vector = LLVMBuildSExt(comp_ctx->builder, vector,
|
||||
vector_ext_type, "zext_to_i64"))) {
|
||||
if (!(vector = LLVMBuildSExt(comp_ctx->builder, vector, vector_ext_type,
|
||||
"zext_to_i64"))) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -74,25 +74,25 @@ simd_build_bitmask(const AOTCompContext *comp_ctx,
|
|||
mask_element[i] = 0x1 << i;
|
||||
}
|
||||
|
||||
if (!(mask = simd_build_const_integer_vector(
|
||||
comp_ctx, I64_TYPE, mask_element, lanes[itype]))) {
|
||||
if (!(mask = simd_build_const_integer_vector(comp_ctx, I64_TYPE,
|
||||
mask_element, lanes[itype]))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(vector =
|
||||
LLVMBuildAnd(comp_ctx->builder, vector, mask, "mask_bits"))) {
|
||||
LLVMBuildAnd(comp_ctx->builder, vector, mask, "mask_bits"))) {
|
||||
HANDLE_FAILURE("LLVMBuildAnd");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
|
||||
I64_TYPE, &vector_ext_type, 1, vector))) {
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
|
||||
I64_TYPE, &vector_ext_type, 1, vector))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildTrunc(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
LLVMBuildTrunc(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
HANDLE_FAILURE("LLVMBuildTrunc");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
v128_bitwise_two_component(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
v128_bitwise_two_component(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Bitwise bitwise_op)
|
||||
{
|
||||
LLVMValueRef vector1, vector2, result;
|
||||
|
@ -27,7 +26,7 @@ v128_bitwise_two_component(AOTCompContext *comp_ctx,
|
|||
break;
|
||||
case V128_OR:
|
||||
if (!(result =
|
||||
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "or"))) {
|
||||
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "or"))) {
|
||||
HANDLE_FAILURE("LLVMBuildAnd");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -95,7 +94,7 @@ v128_bitwise_bitselect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
POP_V128(vector1);
|
||||
|
||||
if (!(vector1 =
|
||||
LLVMBuildAnd(comp_ctx->builder, vector1, vector3, "a_and_c"))) {
|
||||
LLVMBuildAnd(comp_ctx->builder, vector1, vector3, "a_and_c"))) {
|
||||
HANDLE_FAILURE("LLVMBuildAdd");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -106,13 +105,13 @@ v128_bitwise_bitselect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
if (!(vector2 =
|
||||
LLVMBuildAnd(comp_ctx->builder, vector2, vector3, "b_and_c"))) {
|
||||
LLVMBuildAnd(comp_ctx->builder, vector2, vector3, "b_and_c"))) {
|
||||
HANDLE_FAILURE("LLVMBuildAdd");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "a_or_b"))) {
|
||||
LLVMBuildOr(comp_ctx->builder, vector1, vector2, "a_or_b"))) {
|
||||
HANDLE_FAILURE("LLVMBuildOr");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -126,8 +125,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Bitwise bitwise_op)
|
||||
AOTFuncContext *func_ctx, V128Bitwise bitwise_op)
|
||||
{
|
||||
switch (bitwise_op) {
|
||||
case V128_AND:
|
||||
|
|
|
@ -14,8 +14,7 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Bitwise bitwise_op);
|
||||
AOTFuncContext *func_ctx, V128Bitwise bitwise_op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
|
|
@ -16,8 +16,7 @@ enum integer_all_true {
|
|||
};
|
||||
|
||||
static bool
|
||||
simd_all_true(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
simd_all_true(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
enum integer_all_true itype)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
|
@ -56,14 +55,14 @@ simd_all_true(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
/* check zero */
|
||||
if (!(result = aot_call_llvm_intrinsic(comp_ctx, func_ctx,
|
||||
intrinsic[itype], INT1_TYPE,
|
||||
&vector_i1_type, 1, result))) {
|
||||
if (!(result =
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
|
||||
INT1_TYPE, &vector_i1_type, 1, result))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
HANDLE_FAILURE("LLVMBuildZExt");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -120,13 +119,13 @@ aot_compile_simd_v128_any_true(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, "llvm.vector.reduce.or.v128i1", INT1_TYPE,
|
||||
&vector_type, 1, vector))) {
|
||||
comp_ctx, func_ctx, "llvm.vector.reduce.or.v128i1", INT1_TYPE,
|
||||
&vector_type, 1, vector))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
|
||||
HANDLE_FAILURE("LLVMBuildZExt");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
LLVMValueRef
|
||||
simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vec_type,
|
||||
const AOTFuncContext *func_ctx, LLVMTypeRef vec_type,
|
||||
const char *name)
|
||||
{
|
||||
LLVMValueRef number;
|
||||
|
@ -16,7 +15,7 @@ simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
|
|||
POP_V128(number);
|
||||
|
||||
if (!(number =
|
||||
LLVMBuildBitCast(comp_ctx->builder, number, vec_type, name))) {
|
||||
LLVMBuildBitCast(comp_ctx->builder, number, vec_type, name))) {
|
||||
HANDLE_FAILURE("LLVMBuildBitCast");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -28,8 +27,7 @@ fail:
|
|||
|
||||
bool
|
||||
simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
LLVMValueRef vector,
|
||||
const AOTFuncContext *func_ctx, LLVMValueRef vector,
|
||||
const char *name)
|
||||
{
|
||||
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
|
||||
simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const int *element_value,
|
||||
uint32 length)
|
||||
const int *element_value, uint32 length)
|
||||
{
|
||||
LLVMValueRef vector = NULL;
|
||||
LLVMValueRef *elements;
|
||||
|
@ -79,7 +76,7 @@ simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
|
|||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (!(elements[i] =
|
||||
LLVMConstInt(element_type, element_value[i], true))) {
|
||||
LLVMConstInt(element_type, element_value[i], true))) {
|
||||
HANDLE_FAILURE("LLVMConstInst");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -98,8 +95,7 @@ fail:
|
|||
LLVMValueRef
|
||||
simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const int64 element_value,
|
||||
uint32 length)
|
||||
const int64 element_value, uint32 length)
|
||||
{
|
||||
LLVMValueRef vector = NULL, element;
|
||||
LLVMValueRef *elements;
|
||||
|
@ -131,8 +127,7 @@ fail:
|
|||
LLVMValueRef
|
||||
simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const float element_value,
|
||||
uint32 length)
|
||||
const float element_value, uint32 length)
|
||||
{
|
||||
LLVMValueRef vector = NULL, element;
|
||||
LLVMValueRef *elements;
|
||||
|
|
|
@ -17,14 +17,12 @@ is_target_x86(AOTCompContext *comp_ctx)
|
|||
|
||||
LLVMValueRef
|
||||
simd_pop_v128_and_bitcast(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vec_type,
|
||||
const AOTFuncContext *func_ctx, LLVMTypeRef vec_type,
|
||||
const char *name);
|
||||
|
||||
bool
|
||||
simd_bitcast_and_push_v128(const AOTCompContext *comp_ctx,
|
||||
const AOTFuncContext *func_ctx,
|
||||
LLVMValueRef vector,
|
||||
const AOTFuncContext *func_ctx, LLVMValueRef vector,
|
||||
const char *name);
|
||||
|
||||
LLVMValueRef
|
||||
|
@ -33,18 +31,15 @@ simd_lane_id_to_llvm_value(AOTCompContext *comp_ctx, uint8 lane_id);
|
|||
LLVMValueRef
|
||||
simd_build_const_integer_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const int *element_value,
|
||||
uint32 length);
|
||||
const int *element_value, uint32 length);
|
||||
|
||||
LLVMValueRef
|
||||
simd_build_splat_const_integer_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const int64 element_value,
|
||||
uint32 length);
|
||||
const int64 element_value, uint32 length);
|
||||
|
||||
LLVMValueRef
|
||||
simd_build_splat_const_float_vector(const AOTCompContext *comp_ctx,
|
||||
const LLVMTypeRef element_type,
|
||||
const float element_value,
|
||||
uint32 length);
|
||||
const float element_value, uint32 length);
|
||||
#endif /* _SIMD_COMMON_H_ */
|
|
@ -86,10 +86,8 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
interger_vector_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond,
|
||||
LLVMTypeRef vector_type)
|
||||
interger_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
IntCond cond, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef vec1, vec2, result;
|
||||
LLVMIntPredicate int_pred;
|
||||
|
@ -110,14 +108,14 @@ interger_vector_compare(AOTCompContext *comp_ctx,
|
|||
}
|
||||
/* icmp <N x iX> %vec1, %vec2 */
|
||||
if (!(result =
|
||||
LLVMBuildICmp(comp_ctx->builder, int_pred, vec1, vec2, "cmp"))) {
|
||||
LLVMBuildICmp(comp_ctx->builder, int_pred, vec1, vec2, "cmp"))) {
|
||||
HANDLE_FAILURE("LLVMBuildICmp");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* sext <N x i1> %result to <N x iX> */
|
||||
if (!(result =
|
||||
LLVMBuildSExt(comp_ctx->builder, result, vector_type, "ext"))) {
|
||||
LLVMBuildSExt(comp_ctx->builder, result, vector_type, "ext"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSExt");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -138,41 +136,35 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond)
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i8x16_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond)
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i16x8_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond)
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i32x4_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond)
|
||||
AOTFuncContext *func_ctx, IntCond cond)
|
||||
{
|
||||
return interger_vector_compare(comp_ctx, func_ctx, cond, V128_i64x2_TYPE);
|
||||
}
|
||||
|
||||
static bool
|
||||
float_vector_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatCond cond,
|
||||
LLVMTypeRef vector_type,
|
||||
float_vector_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatCond cond, LLVMTypeRef vector_type,
|
||||
LLVMTypeRef result_type)
|
||||
{
|
||||
LLVMValueRef vec1, vec2, result;
|
||||
|
@ -194,14 +186,14 @@ float_vector_compare(AOTCompContext *comp_ctx,
|
|||
}
|
||||
/* fcmp <N x iX> %vec1, %vec2 */
|
||||
if (!(result =
|
||||
LLVMBuildFCmp(comp_ctx->builder, real_pred, vec1, vec2, "cmp"))) {
|
||||
LLVMBuildFCmp(comp_ctx->builder, real_pred, vec1, vec2, "cmp"))) {
|
||||
HANDLE_FAILURE("LLVMBuildFCmp");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* sext <N x i1> %result to <N x iX> */
|
||||
if (!(result =
|
||||
LLVMBuildSExt(comp_ctx->builder, result, result_type, "ext"))) {
|
||||
LLVMBuildSExt(comp_ctx->builder, result, result_type, "ext"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSExt");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -222,8 +214,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatCond cond)
|
||||
AOTFuncContext *func_ctx, FloatCond cond)
|
||||
{
|
||||
return float_vector_compare(comp_ctx, func_ctx, cond, V128_f32x4_TYPE,
|
||||
V128_i32x4_TYPE);
|
||||
|
@ -231,8 +222,7 @@ aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatCond cond)
|
||||
AOTFuncContext *func_ctx, FloatCond cond)
|
||||
{
|
||||
return float_vector_compare(comp_ctx, func_ctx, cond, V128_f64x2_TYPE,
|
||||
V128_i64x2_TYPE);
|
||||
|
|
|
@ -14,33 +14,27 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_simd_i8x16_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond);
|
||||
AOTFuncContext *func_ctx, IntCond cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond);
|
||||
AOTFuncContext *func_ctx, IntCond cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond);
|
||||
AOTFuncContext *func_ctx, IntCond cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
IntCond cond);
|
||||
AOTFuncContext *func_ctx, IntCond cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatCond cond);
|
||||
AOTFuncContext *func_ctx, FloatCond cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_compare(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatCond cond);
|
||||
AOTFuncContext *func_ctx, FloatCond cond);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_const(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_v128_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *imm_bytes)
|
||||
{
|
||||
uint64 imm1, imm2;
|
||||
|
@ -26,8 +25,8 @@ aot_compile_simd_v128_const(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(agg1 =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, LLVM_CONST(i64x2_undef),
|
||||
first_long, I32_ZERO, "agg1"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, LLVM_CONST(i64x2_undef),
|
||||
first_long, I32_ZERO, "agg1"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -51,8 +50,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_splat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode)
|
||||
{
|
||||
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),
|
||||
};
|
||||
LLVMValueRef masks[] = {
|
||||
LLVM_CONST(i32x16_zero), LLVM_CONST(i32x8_zero),
|
||||
LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero),
|
||||
LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero),
|
||||
LLVM_CONST(i32x16_zero), LLVM_CONST(i32x8_zero), LLVM_CONST(i32x4_zero),
|
||||
LLVM_CONST(i32x2_zero), LLVM_CONST(i32x4_zero), LLVM_CONST(i32x2_zero),
|
||||
};
|
||||
|
||||
switch (opcode) {
|
||||
|
@ -75,7 +72,7 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
|
|||
POP_I32(input);
|
||||
/* trunc i32 %input to i8 */
|
||||
value =
|
||||
LLVMBuildTrunc(comp_ctx->builder, input, INT8_TYPE, "trunc");
|
||||
LLVMBuildTrunc(comp_ctx->builder, input, INT8_TYPE, "trunc");
|
||||
break;
|
||||
}
|
||||
case SIMD_i16x8_splat:
|
||||
|
@ -84,7 +81,7 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
|
|||
POP_I32(input);
|
||||
/* trunc i32 %input to i16 */
|
||||
value =
|
||||
LLVMBuildTrunc(comp_ctx->builder, input, INT16_TYPE, "trunc");
|
||||
LLVMBuildTrunc(comp_ctx->builder, input, INT16_TYPE, "trunc");
|
||||
break;
|
||||
}
|
||||
case SIMD_i32x4_splat:
|
||||
|
@ -118,23 +115,21 @@ aot_compile_simd_splat(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
/* insertelement <n x ty> undef, ty %value, i32 0 */
|
||||
if (!(base =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
|
||||
value, I32_ZERO, "base"))) {
|
||||
if (!(base = LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
|
||||
value, I32_ZERO, "base"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* shufflevector <ty1> %base, <ty2> undef, <n x i32> zeroinitializer */
|
||||
if (!(new_vector = LLVMBuildShuffleVector(
|
||||
comp_ctx->builder, base, undefs[opcode_index], masks[opcode_index],
|
||||
"new_vector"))) {
|
||||
comp_ctx->builder, base, undefs[opcode_index],
|
||||
masks[opcode_index], "new_vector"))) {
|
||||
HANDLE_FAILURE("LLVMBuildShuffleVector");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, new_vector,
|
||||
"result");
|
||||
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, new_vector, "result");
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_const(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_v128_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *imm_bytes);
|
||||
|
||||
bool
|
||||
aot_compile_simd_splat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 splat_opcode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
simd_integer_narrow_x86(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef in_vector_type,
|
||||
LLVMTypeRef out_vector_type,
|
||||
simd_integer_narrow_x86(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef in_vector_type, LLVMTypeRef out_vector_type,
|
||||
const char *instrinsic)
|
||||
{
|
||||
LLVMValueRef vector1, vector2, result;
|
||||
|
@ -44,13 +42,9 @@ enum integer_sat_type {
|
|||
};
|
||||
|
||||
static LLVMValueRef
|
||||
simd_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
enum integer_sat_type itype,
|
||||
LLVMValueRef vector,
|
||||
LLVMValueRef min,
|
||||
LLVMValueRef max,
|
||||
bool is_signed)
|
||||
simd_saturate(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
enum integer_sat_type itype, LLVMValueRef vector,
|
||||
LLVMValueRef min, LLVMValueRef max, bool is_signed)
|
||||
{
|
||||
LLVMValueRef result;
|
||||
LLVMTypeRef vector_type;
|
||||
|
@ -101,13 +95,13 @@ simd_saturate(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx,
|
||||
is_signed ? smin_intrinsic[itype] : umin_intrinsic[itype],
|
||||
param_types[itype][0], param_types[itype], 2, vector, max))
|
||||
comp_ctx, func_ctx,
|
||||
is_signed ? smin_intrinsic[itype] : umin_intrinsic[itype],
|
||||
param_types[itype][0], param_types[itype], 2, vector, max))
|
||||
|| !(result = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx,
|
||||
is_signed ? smax_intrinsic[itype] : umax_intrinsic[itype],
|
||||
param_types[itype][0], param_types[itype], 2, result, min))) {
|
||||
comp_ctx, func_ctx,
|
||||
is_signed ? smax_intrinsic[itype] : umax_intrinsic[itype],
|
||||
param_types[itype][0], param_types[itype], 2, result, min))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -115,10 +109,8 @@ simd_saturate(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
static bool
|
||||
simd_integer_narrow_common(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
enum integer_sat_type itype,
|
||||
bool is_signed)
|
||||
simd_integer_narrow_common(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
enum integer_sat_type itype, bool is_signed)
|
||||
{
|
||||
LLVMValueRef vec1, vec2, min, max, mask, result;
|
||||
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,
|
||||
in_vector_type[itype], "vec2"))
|
||||
|| !(vec1 = simd_pop_v128_and_bitcast(
|
||||
comp_ctx, func_ctx, in_vector_type[itype], "vec1"))) {
|
||||
|| !(vec1 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
|
||||
in_vector_type[itype], "vec1"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(max = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, min_max_type[itype],
|
||||
is_signed ? smax[itype] : umax[itype], length[itype]))
|
||||
comp_ctx, min_max_type[itype],
|
||||
is_signed ? smax[itype] : umax[itype], length[itype]))
|
||||
|| !(min = simd_build_splat_const_integer_vector(
|
||||
comp_ctx, min_max_type[itype],
|
||||
is_signed ? smin[itype] : umin[itype], length[itype]))) {
|
||||
comp_ctx, min_max_type[itype],
|
||||
is_signed ? smin[itype] : umin[itype], length[itype]))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -200,14 +192,13 @@ simd_integer_narrow_common(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
if (is_target_x86(comp_ctx)) {
|
||||
return simd_integer_narrow_x86(
|
||||
comp_ctx, func_ctx, V128_i16x8_TYPE, V128_i8x16_TYPE,
|
||||
is_signed ? "llvm.x86.sse2.packsswb.128"
|
||||
: "llvm.x86.sse2.packuswb.128");
|
||||
comp_ctx, func_ctx, V128_i16x8_TYPE, V128_i8x16_TYPE,
|
||||
is_signed ? "llvm.x86.sse2.packsswb.128"
|
||||
: "llvm.x86.sse2.packuswb.128");
|
||||
}
|
||||
else {
|
||||
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
|
||||
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
if (is_target_x86(comp_ctx)) {
|
||||
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
|
||||
aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
/* TODO: x86 intrinsics */
|
||||
return simd_integer_narrow_common(comp_ctx, func_ctx, e_sat_i64x2,
|
||||
|
@ -249,12 +238,9 @@ enum integer_extend_type {
|
|||
};
|
||||
|
||||
static LLVMValueRef
|
||||
simd_integer_extension(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
enum integer_extend_type itype,
|
||||
LLVMValueRef vector,
|
||||
bool lower_half,
|
||||
bool is_signed)
|
||||
simd_integer_extension(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
enum integer_extend_type itype, LLVMValueRef vector,
|
||||
bool lower_half, bool is_signed)
|
||||
{
|
||||
LLVMValueRef mask, sub_vector, result;
|
||||
LLVMValueRef bits[] = {
|
||||
|
@ -308,8 +294,7 @@ simd_integer_extension(AOTCompContext *comp_ctx,
|
|||
static bool
|
||||
simd_integer_extension_wrapper(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
enum integer_extend_type itype,
|
||||
bool lower_half,
|
||||
enum integer_extend_type itype, bool lower_half,
|
||||
bool is_signed)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
|
@ -332,8 +317,7 @@ simd_integer_extension_wrapper(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed)
|
||||
{
|
||||
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
|
||||
aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed)
|
||||
{
|
||||
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
|
||||
aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed)
|
||||
{
|
||||
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
|
||||
simd_trunc_sat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const char *intrinsics,
|
||||
LLVMTypeRef in_vector_type,
|
||||
simd_trunc_sat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const char *intrinsics, LLVMTypeRef in_vector_type,
|
||||
LLVMTypeRef out_vector_type)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
LLVMTypeRef param_types[] = { in_vector_type };
|
||||
|
||||
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
|
||||
in_vector_type, "vector"))) {
|
||||
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, in_vector_type,
|
||||
"vector"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -386,8 +366,7 @@ simd_trunc_sat(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i32x4_trunc_sat_f32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
LLVMValueRef result;
|
||||
if (!(result = simd_trunc_sat(comp_ctx, func_ctx,
|
||||
|
@ -402,8 +381,7 @@ aot_compile_simd_i32x4_trunc_sat_f32x4(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
LLVMValueRef result, zero, mask;
|
||||
LLVMTypeRef out_vector_type;
|
||||
|
@ -425,7 +403,7 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
|
|||
V128_f64x2_TYPE, out_vector_type))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!(zero = LLVMConstNull(out_vector_type))) {
|
||||
HANDLE_FAILURE("LLVMConstNull");
|
||||
return false;
|
||||
|
@ -437,8 +415,8 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result, zero,
|
||||
mask, "extend"))) {
|
||||
if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result, zero, mask,
|
||||
"extend"))) {
|
||||
HANDLE_FAILURE("LLVMBuildShuffleVector");
|
||||
return false;
|
||||
}
|
||||
|
@ -447,10 +425,8 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
static LLVMValueRef
|
||||
simd_integer_convert(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed,
|
||||
LLVMValueRef vector,
|
||||
simd_integer_convert(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool is_signed, LLVMValueRef vector,
|
||||
LLVMTypeRef out_vector_type)
|
||||
|
||||
{
|
||||
|
@ -468,8 +444,7 @@ simd_integer_convert(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
|
||||
|
@ -488,8 +463,7 @@ aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed)
|
||||
AOTFuncContext *func_ctx, bool is_signed)
|
||||
{
|
||||
LLVMValueRef vector, mask, result;
|
||||
LLVMValueRef lanes[] = {
|
||||
|
@ -529,14 +503,12 @@ aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
static bool
|
||||
simd_extadd_pairwise(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef in_vector_type,
|
||||
LLVMTypeRef out_vector_type,
|
||||
simd_extadd_pairwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef in_vector_type, LLVMTypeRef out_vector_type,
|
||||
bool is_signed)
|
||||
{
|
||||
LLVMValueRef vector, even_mask, odd_mask, sub_vector_even, sub_vector_odd,
|
||||
result;
|
||||
result;
|
||||
|
||||
LLVMValueRef even_element[] = {
|
||||
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 */
|
||||
uint8 mask_length = V128_i16x8_TYPE == out_vector_type ? 8 : 4;
|
||||
|
||||
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
|
||||
in_vector_type, "vector"))) {
|
||||
if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, in_vector_type,
|
||||
"vector"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -567,9 +539,9 @@ simd_extadd_pairwise(AOTCompContext *comp_ctx,
|
|||
|
||||
/* shuffle a <16xi8> vector to two <8xi8> vectors */
|
||||
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(
|
||||
comp_ctx->builder, vector, vector, odd_mask, "pick_odd"))) {
|
||||
comp_ctx->builder, vector, vector, odd_mask, "pick_odd"))) {
|
||||
HANDLE_FAILURE("LLVMBuildShuffleVector");
|
||||
return false;
|
||||
}
|
||||
|
@ -577,22 +549,22 @@ simd_extadd_pairwise(AOTCompContext *comp_ctx,
|
|||
/* sext/zext <8xi8> to <8xi16> */
|
||||
if (is_signed) {
|
||||
if (!(sub_vector_even =
|
||||
LLVMBuildSExt(comp_ctx->builder, sub_vector_even,
|
||||
out_vector_type, "even_sext"))
|
||||
LLVMBuildSExt(comp_ctx->builder, sub_vector_even,
|
||||
out_vector_type, "even_sext"))
|
||||
|| !(sub_vector_odd =
|
||||
LLVMBuildSExt(comp_ctx->builder, sub_vector_odd,
|
||||
out_vector_type, "odd_sext"))) {
|
||||
LLVMBuildSExt(comp_ctx->builder, sub_vector_odd,
|
||||
out_vector_type, "odd_sext"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSExt");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(sub_vector_even =
|
||||
LLVMBuildZExt(comp_ctx->builder, sub_vector_even,
|
||||
out_vector_type, "even_zext"))
|
||||
LLVMBuildZExt(comp_ctx->builder, sub_vector_even,
|
||||
out_vector_type, "even_zext"))
|
||||
|| !(sub_vector_odd =
|
||||
LLVMBuildZExt(comp_ctx->builder, sub_vector_odd,
|
||||
out_vector_type, "odd_zext"))) {
|
||||
LLVMBuildZExt(comp_ctx->builder, sub_vector_odd,
|
||||
out_vector_type, "odd_zext"))) {
|
||||
HANDLE_FAILURE("LLVMBuildZExt");
|
||||
return false;
|
||||
}
|
||||
|
@ -706,10 +678,8 @@ enum integer_extmul_type {
|
|||
};
|
||||
|
||||
static bool
|
||||
simd_integer_extmul(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
bool is_signed,
|
||||
simd_integer_extmul(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool lower_half, bool is_signed,
|
||||
enum integer_extmul_type itype)
|
||||
{
|
||||
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,
|
||||
in_vector_type[itype], "vec1"))
|
||||
|| !(vec2 = simd_pop_v128_and_bitcast(
|
||||
comp_ctx, func_ctx, in_vector_type[itype], "vec2"))) {
|
||||
|| !(vec2 = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
|
||||
in_vector_type[itype], "vec2"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -747,8 +717,7 @@ simd_integer_extmul(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool 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
|
||||
aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool 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
|
||||
aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed)
|
||||
{
|
||||
return simd_integer_extmul(comp_ctx, func_ctx, lower_half, is_signed,
|
||||
|
|
|
@ -14,35 +14,29 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_simd_i8x16_narrow_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed);
|
||||
AOTFuncContext *func_ctx, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_narrow_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed);
|
||||
AOTFuncContext *func_ctx, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_narrow_i64x2(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed);
|
||||
AOTFuncContext *func_ctx, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_extend_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_low,
|
||||
AOTFuncContext *func_ctx, bool is_low,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_extend_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_low,
|
||||
AOTFuncContext *func_ctx, bool is_low,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_extend_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
|
@ -57,13 +51,11 @@ aot_compile_simd_i32x4_trunc_sat_f64x2(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f32x4_convert_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed);
|
||||
AOTFuncContext *func_ctx, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_convert_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_signed);
|
||||
AOTFuncContext *func_ctx, bool is_signed);
|
||||
bool
|
||||
aot_compile_simd_i16x8_extadd_pairwise_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
|
@ -79,20 +71,17 @@ aot_compile_simd_i16x8_q15mulr_sat(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_i16x8_extmul_i8x16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_low,
|
||||
AOTFuncContext *func_ctx, bool is_low,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_extmul_i16x8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool is_low,
|
||||
AOTFuncContext *func_ctx, bool is_low,
|
||||
bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_extmul_i32x4(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool lower_half,
|
||||
AOTFuncContext *func_ctx, bool lower_half,
|
||||
bool is_signed);
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
|
|
|
@ -10,15 +10,13 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
simd_v128_float_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op,
|
||||
LLVMTypeRef vector_type)
|
||||
simd_v128_float_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result = NULL;
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
|
@ -43,7 +41,7 @@ simd_v128_float_arith(AOTCompContext *comp_ctx,
|
|||
|
||||
if (!result) {
|
||||
HANDLE_FAILURE(
|
||||
"LLVMBuildFAdd/LLVMBuildFSub/LLVMBuildFMul/LLVMBuildFDiv");
|
||||
"LLVMBuildFAdd/LLVMBuildFSub/LLVMBuildFMul/LLVMBuildFDiv");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -51,26 +49,21 @@ simd_v128_float_arith(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op)
|
||||
{
|
||||
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op,
|
||||
V128_f32x4_TYPE);
|
||||
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, V128_f32x4_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op)
|
||||
{
|
||||
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op,
|
||||
V128_f64x2_TYPE);
|
||||
return simd_v128_float_arith(comp_ctx, func_ctx, arith_op, V128_f64x2_TYPE);
|
||||
}
|
||||
|
||||
static bool
|
||||
simd_v128_float_neg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
simd_v128_float_neg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
|
@ -101,10 +94,8 @@ aot_compile_simd_f64x2_neg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
static bool
|
||||
simd_float_intrinsic(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type,
|
||||
const char *intrinsic)
|
||||
simd_float_intrinsic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type, const char *intrinsic)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
LLVMTypeRef param_types[1] = { vector_type };
|
||||
|
@ -115,8 +106,8 @@ simd_float_intrinsic(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result =
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, vector_type,
|
||||
param_types, 1, vector))) {
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
|
||||
vector_type, param_types, 1, vector))) {
|
||||
HANDLE_FAILURE("LLVMBuildCall");
|
||||
return false;
|
||||
}
|
||||
|
@ -139,16 +130,14 @@ aot_compile_simd_f64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f32x4_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
|
||||
"llvm.round.v4f32");
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
|
||||
"llvm.round.v2f64");
|
||||
|
@ -183,32 +172,28 @@ aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
|
||||
"llvm.floor.v4f32");
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_floor(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f64x2_floor(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
|
||||
"llvm.floor.v2f64");
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_trunc(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f32x4_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f32x4_TYPE,
|
||||
"llvm.trunc.v4f32");
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_trunc(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
aot_compile_simd_f64x2_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_float_intrinsic(comp_ctx, func_ctx, V128_f64x2_TYPE,
|
||||
"llvm.trunc.v2f64");
|
||||
|
@ -231,16 +216,14 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
static bool
|
||||
simd_float_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op,
|
||||
LLVMTypeRef vector_type)
|
||||
simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result;
|
||||
LLVMRealPredicate op = FLOAT_MIN == arith_op ? LLVMRealULT : LLVMRealUGT;
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
|
@ -252,7 +235,7 @@ simd_float_cmp(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
|
||||
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSelect");
|
||||
return false;
|
||||
}
|
||||
|
@ -260,11 +243,11 @@ simd_float_cmp(AOTCompContext *comp_ctx,
|
|||
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
|
||||
aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min)
|
||||
AOTFuncContext *func_ctx, bool run_min)
|
||||
{
|
||||
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
|
||||
V128_f32x4_TYPE);
|
||||
|
@ -272,18 +255,15 @@ aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min)
|
||||
AOTFuncContext *func_ctx, bool run_min)
|
||||
{
|
||||
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
|
||||
V128_f64x2_TYPE);
|
||||
}
|
||||
|
||||
static bool
|
||||
simd_float_pmin_max(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type,
|
||||
const char *intrinsic)
|
||||
simd_float_pmin_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type, const char *intrinsic)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result;
|
||||
LLVMTypeRef param_types[2];
|
||||
|
@ -292,15 +272,15 @@ simd_float_pmin_max(AOTCompContext *comp_ctx,
|
|||
param_types[1] = vector_type;
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(result =
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, vector_type,
|
||||
param_types, 2, lhs, rhs))) {
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
|
||||
vector_type, param_types, 2, lhs, rhs))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -309,8 +289,7 @@ simd_float_pmin_max(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min)
|
||||
AOTFuncContext *func_ctx, bool run_min)
|
||||
{
|
||||
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f32x4_TYPE,
|
||||
run_min ? "llvm.minnum.v4f32"
|
||||
|
@ -319,8 +298,7 @@ aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min)
|
||||
AOTFuncContext *func_ctx, bool run_min)
|
||||
{
|
||||
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f64x2_TYPE,
|
||||
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,
|
||||
LLVM_CONST(i32_zero), "elem_0"))
|
||||
|| !(elem_1 = LLVMBuildExtractElement(
|
||||
comp_ctx->builder, vector, LLVM_CONST(i32_one), "elem_1"))) {
|
||||
|| !(elem_1 = LLVMBuildExtractElement(comp_ctx->builder, vector,
|
||||
LLVM_CONST(i32_one), "elem_1"))) {
|
||||
HANDLE_FAILURE("LLVMBuildExtractElement");
|
||||
return false;
|
||||
}
|
||||
|
@ -355,12 +333,12 @@ aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(result = LLVMBuildInsertElement(
|
||||
comp_ctx->builder, LLVM_CONST(f32x4_vec_zero), elem_0,
|
||||
LLVM_CONST(i32_zero), "new_vector_0"))
|
||||
if (!(result = LLVMBuildInsertElement(comp_ctx->builder,
|
||||
LLVM_CONST(f32x4_vec_zero), elem_0,
|
||||
LLVM_CONST(i32_zero), "new_vector_0"))
|
||||
|| !(result =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,
|
||||
LLVM_CONST(i32_one), "new_vector_1"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,
|
||||
LLVM_CONST(i32_one), "new_vector_1"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
return false;
|
||||
}
|
||||
|
@ -381,27 +359,27 @@ aot_compile_simd_f32x4_promote(AOTCompContext *comp_ctx,
|
|||
|
||||
if (!(elem_0 = LLVMBuildExtractElement(comp_ctx->builder, vector,
|
||||
LLVM_CONST(i32_zero), "elem_0"))
|
||||
|| !(elem_1 = LLVMBuildExtractElement(
|
||||
comp_ctx->builder, vector, LLVM_CONST(i32_one), "elem_1"))) {
|
||||
|| !(elem_1 = LLVMBuildExtractElement(comp_ctx->builder, vector,
|
||||
LLVM_CONST(i32_one), "elem_1"))) {
|
||||
HANDLE_FAILURE("LLVMBuildExtractElement");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* fpext <f32> elem to <f64> */
|
||||
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_ext"))) {
|
||||
HANDLE_FAILURE("LLVMBuildFPExt");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(result = LLVMBuildInsertElement(
|
||||
comp_ctx->builder, LLVM_CONST(f64x2_vec_zero), elem_0,
|
||||
LLVM_CONST(i32_zero), "new_vector_0"))
|
||||
if (!(result = LLVMBuildInsertElement(comp_ctx->builder,
|
||||
LLVM_CONST(f64x2_vec_zero), elem_0,
|
||||
LLVM_CONST(i32_zero), "new_vector_0"))
|
||||
|| !(result =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,
|
||||
LLVM_CONST(i32_one), "new_vector_1"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, result, elem_1,
|
||||
LLVM_CONST(i32_one), "new_vector_1"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_f32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_f64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
FloatArithmetic arith_op);
|
||||
|
||||
bool
|
||||
|
@ -43,20 +41,16 @@ aot_compile_simd_f64x2_round(AOTCompContext *comp_ctx,
|
|||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
aot_compile_simd_f32x4_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_sqrt(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
aot_compile_simd_f64x2_sqrt(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_ceil(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
aot_compile_simd_f32x4_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
aot_compile_simd_f64x2_ceil(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_floor(AOTCompContext *comp_ctx,
|
||||
|
@ -84,23 +78,19 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min);
|
||||
AOTFuncContext *func_ctx, bool run_min);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min);
|
||||
AOTFuncContext *func_ctx, bool run_min);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min);
|
||||
AOTFuncContext *func_ctx, bool run_min);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
bool run_min);
|
||||
AOTFuncContext *func_ctx, bool run_min);
|
||||
|
||||
bool
|
||||
aot_compile_simd_f64x2_demote(AOTCompContext *comp_ctx,
|
||||
|
|
|
@ -9,15 +9,13 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
simd_integer_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
LLVMTypeRef vector_type)
|
||||
simd_integer_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result = NULL;
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
|
@ -47,32 +45,28 @@ simd_integer_arith(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op)
|
||||
{
|
||||
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i8x16_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op)
|
||||
{
|
||||
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i16x8_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op)
|
||||
{
|
||||
return simd_integer_arith(comp_ctx, func_ctx, arith_op, V128_i32x4_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -141,17 +135,14 @@ aot_compile_simd_i8x16_popcnt(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
static bool
|
||||
simd_v128_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
simd_v128_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type, V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result;
|
||||
LLVMIntPredicate op;
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
|
@ -170,7 +161,7 @@ simd_v128_cmp(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
|
||||
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
|
||||
HANDLE_FAILURE("LLVMBuildSelect");
|
||||
return false;
|
||||
}
|
||||
|
@ -179,30 +170,24 @@ simd_v128_cmp(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
return simd_v128_cmp(comp_ctx, func_ctx, V128_i8x16_TYPE, arith_op,
|
||||
is_signed);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
return simd_v128_cmp(comp_ctx, func_ctx, V128_i16x8_TYPE, arith_op,
|
||||
is_signed);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
return simd_v128_cmp(comp_ctx, func_ctx, V128_i32x4_TYPE, arith_op,
|
||||
is_signed);
|
||||
|
@ -210,10 +195,8 @@ aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx,
|
|||
|
||||
/* llvm.abs.* */
|
||||
static bool
|
||||
simd_v128_abs(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
char *intrinsic,
|
||||
LLVMTypeRef vector_type)
|
||||
simd_v128_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
char *intrinsic, LLVMTypeRef vector_type)
|
||||
{
|
||||
LLVMValueRef vector, result;
|
||||
LLVMTypeRef param_types[] = { vector_type, INT1_TYPE };
|
||||
|
@ -236,29 +219,25 @@ simd_v128_abs(AOTCompContext *comp_ctx,
|
|||
bool
|
||||
aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v16i8",
|
||||
V128_i8x16_TYPE);
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v16i8", V128_i8x16_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v8i16",
|
||||
V128_i16x8_TYPE);
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v8i16", V128_i16x8_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v4i32",
|
||||
V128_i32x4_TYPE);
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v4i32", V128_i32x4_TYPE);
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v2i64",
|
||||
V128_i64x2_TYPE);
|
||||
return simd_v128_abs(comp_ctx, func_ctx, "llvm.abs.v2i64", V128_i64x2_TYPE);
|
||||
}
|
||||
|
||||
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 */
|
||||
/* (v1 + v2 + 1) / 2 */
|
||||
static bool
|
||||
simd_v128_avg(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
simd_v128_avg(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
enum integer_avgr_u itype)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, ones, result;
|
||||
|
@ -324,8 +302,8 @@ simd_v128_avg(AOTCompContext *comp_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(result = LLVMBuildTrunc(comp_ctx->builder, result,
|
||||
vector_type[itype], "to_orig_type"))) {
|
||||
if (!(result = LLVMBuildTrunc(comp_ctx->builder, result, vector_type[itype],
|
||||
"to_orig_type"))) {
|
||||
HANDLE_FAILURE("LLVMBuildTrunc");
|
||||
return false;
|
||||
}
|
||||
|
@ -406,8 +384,8 @@ aot_compile_simd_i32x4_dot_i16x8(AOTCompContext *comp_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(zero =
|
||||
simd_build_splat_const_integer_vector(comp_ctx, I32_TYPE, 0, 8))) {
|
||||
if (!(zero = simd_build_splat_const_integer_vector(comp_ctx, I32_TYPE, 0,
|
||||
8))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,23 +13,19 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i8x16_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i16x8_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i32x4_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic cond);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
aot_compile_simd_i64x2_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic cond);
|
||||
|
||||
bool
|
||||
|
@ -49,22 +45,16 @@ aot_compile_simd_i8x16_popcnt(AOTCompContext *comp_ctx,
|
|||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
aot_compile_simd_i8x16_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
aot_compile_simd_i16x8_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
aot_compile_simd_i32x4_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i8x16_abs(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
|
|
@ -12,12 +12,8 @@
|
|||
|
||||
/* data_length in bytes */
|
||||
static LLVMValueRef
|
||||
simd_load(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
uint32 data_length,
|
||||
LLVMTypeRef ptr_type)
|
||||
simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 data_length, LLVMTypeRef ptr_type)
|
||||
{
|
||||
LLVMValueRef maddr, data;
|
||||
|
||||
|
@ -44,15 +40,13 @@ simd_load(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset)
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
{
|
||||
LLVMValueRef result;
|
||||
|
||||
if (!(result =
|
||||
simd_load(comp_ctx, func_ctx, align, offset, 16, V128_PTR_TYPE))) {
|
||||
if (!(result = simd_load(comp_ctx, func_ctx, align, offset, 16,
|
||||
V128_PTR_TYPE))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -64,11 +58,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset)
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
{
|
||||
LLVMValueRef sub_vector, result;
|
||||
uint32 opcode_index = opcode - SIMD_v128_load8x8_s;
|
||||
|
@ -119,11 +110,8 @@ aot_compile_simd_load_extend(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset)
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
{
|
||||
uint32 opcode_index = opcode - SIMD_v128_load8_splat;
|
||||
LLVMValueRef element, result;
|
||||
|
@ -152,8 +140,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
|
||||
element, I32_ZERO, "base"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
|
||||
element, I32_ZERO, "base"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
return false;
|
||||
}
|
||||
|
@ -169,11 +157,8 @@ aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 lane_id)
|
||||
{
|
||||
LLVMValueRef element, vector;
|
||||
|
@ -188,7 +173,7 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
|
|||
bh_assert(opcode_index < 4);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -208,11 +193,8 @@ aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset)
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset)
|
||||
{
|
||||
LLVMValueRef element, result, mask;
|
||||
uint32 opcode_index = opcode - SIMD_v128_load32_zero;
|
||||
|
@ -242,8 +224,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (!(result =
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef[opcode_index],
|
||||
element, I32_ZERO, "vector"))) {
|
||||
LLVMBuildInsertElement(comp_ctx->builder, undef[opcode_index],
|
||||
element, I32_ZERO, "vector"))) {
|
||||
HANDLE_FAILURE("LLVMBuildInsertElement");
|
||||
return false;
|
||||
}
|
||||
|
@ -267,12 +249,8 @@ aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
|
|||
|
||||
/* data_length in bytes */
|
||||
static bool
|
||||
simd_store(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
uint32 data_length,
|
||||
LLVMValueRef value,
|
||||
simd_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
|
||||
uint32 offset, uint32 data_length, LLVMValueRef value,
|
||||
LLVMTypeRef value_ptr_type)
|
||||
{
|
||||
LLVMValueRef maddr, result;
|
||||
|
@ -298,10 +276,8 @@ simd_store(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset)
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset)
|
||||
{
|
||||
LLVMValueRef value;
|
||||
|
||||
|
@ -314,11 +290,8 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 lane_id)
|
||||
{
|
||||
LLVMValueRef element, vector;
|
||||
|
@ -333,7 +306,7 @@ aot_compile_simd_store_lane(AOTCompContext *comp_ctx,
|
|||
bh_assert(opcode_index < 4);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,52 +13,33 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset);
|
||||
aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset);
|
||||
aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset);
|
||||
aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 lane_id);
|
||||
|
||||
bool
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset);
|
||||
aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint32 align,
|
||||
uint32 offset);
|
||||
aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 align, uint32 offset);
|
||||
|
||||
bool
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
uint8 opcode,
|
||||
uint32 align,
|
||||
uint32 offset,
|
||||
aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint8 opcode, uint32 align, uint32 offset,
|
||||
uint8 lane_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -9,16 +9,14 @@
|
|||
#include "../../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
simd_sat_int_arith(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type,
|
||||
const char *intrinsics)
|
||||
simd_sat_int_arith(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMTypeRef vector_type, const char *intrinsics)
|
||||
{
|
||||
LLVMValueRef lhs, rhs, result;
|
||||
LLVMTypeRef param_types[2];
|
||||
|
||||
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"))) {
|
||||
return false;
|
||||
|
@ -28,8 +26,8 @@ simd_sat_int_arith(AOTCompContext *comp_ctx,
|
|||
param_types[1] = vector_type;
|
||||
|
||||
if (!(result =
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsics,
|
||||
vector_type, param_types, 2, lhs, rhs))) {
|
||||
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsics,
|
||||
vector_type, param_types, 2, lhs, rhs))) {
|
||||
HANDLE_FAILURE("LLVMBuildCall");
|
||||
return false;
|
||||
}
|
||||
|
@ -40,8 +38,7 @@ simd_sat_int_arith(AOTCompContext *comp_ctx,
|
|||
bool
|
||||
aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
char *intrinsics[][2] = {
|
||||
{ "llvm.sadd.sat.v16i8", "llvm.uadd.sat.v16i8" },
|
||||
|
@ -56,8 +53,7 @@ aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
|
|||
bool
|
||||
aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
char *intrinsics[][2] = {
|
||||
{ "llvm.sadd.sat.v8i16", "llvm.uadd.sat.v8i16" },
|
||||
|
@ -72,8 +68,7 @@ aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
|
|||
bool
|
||||
aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed)
|
||||
V128Arithmetic arith_op, bool is_signed)
|
||||
{
|
||||
char *intrinsics[][2] = {
|
||||
{ "llvm.sadd.sat.v4i32", "llvm.uadd.sat.v4i32" },
|
||||
|
|
|
@ -15,20 +15,17 @@ extern "C" {
|
|||
bool
|
||||
aot_compile_simd_i8x16_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i16x8_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
|
||||
bool
|
||||
aot_compile_simd_i32x4_saturate(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
V128Arithmetic arith_op,
|
||||
bool is_signed);
|
||||
V128Arithmetic arith_op, bool is_signed);
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
|
|
@ -59,14 +59,13 @@ control_thread_routine(void *arg)
|
|||
control_thread->debug_engine = g_debug_engine;
|
||||
control_thread->debug_instance = debug_inst;
|
||||
strcpy(control_thread->ip_addr, g_debug_engine->ip_addr);
|
||||
control_thread->port =
|
||||
g_debug_engine->process_base_port + debug_inst->id;
|
||||
control_thread->port = g_debug_engine->process_base_port + debug_inst->id;
|
||||
|
||||
LOG_WARNING("control thread of debug object %p start at %s:%d\n",
|
||||
debug_inst, control_thread->ip_addr, control_thread->port);
|
||||
|
||||
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) {
|
||||
LOG_ERROR("Failed to create debug server\n");
|
||||
os_cond_signal(&exec_env->wait_cond);
|
||||
|
@ -110,7 +109,7 @@ wasm_debug_control_thread_create(WASMDebugInstance *debug_instance)
|
|||
bh_assert(exec_env);
|
||||
|
||||
if (!(control_thread =
|
||||
wasm_runtime_malloc(sizeof(WASMDebugControlThread)))) {
|
||||
wasm_runtime_malloc(sizeof(WASMDebugControlThread)))) {
|
||||
LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -123,8 +122,9 @@ wasm_debug_control_thread_create(WASMDebugInstance *debug_instance)
|
|||
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
|
||||
if (0 != os_thread_create(&control_thread->tid, control_thread_routine,
|
||||
debug_instance, APP_THREAD_STACK_SIZE_MAX)) {
|
||||
if (0
|
||||
!= os_thread_create(&control_thread->tid, control_thread_routine,
|
||||
debug_instance, APP_THREAD_STACK_SIZE_MAX)) {
|
||||
os_mutex_unlock(&control_thread->wait_lock);
|
||||
goto fail1;
|
||||
}
|
||||
|
@ -153,8 +153,7 @@ wasm_debug_control_thread_destroy(WASMDebugInstance *debug_instance)
|
|||
{
|
||||
WASMDebugControlThread *control_thread = debug_instance->control_thread;
|
||||
LOG_VERBOSE("control thread of debug object %p stop at %s:%d\n",
|
||||
debug_instance, control_thread->ip_addr,
|
||||
control_thread->port);
|
||||
debug_instance, control_thread->ip_addr, control_thread->port);
|
||||
control_thread->status = STOPPED;
|
||||
os_mutex_lock(&control_thread->wait_lock);
|
||||
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) {
|
||||
process_port -= 1;
|
||||
g_debug_engine->platform_port =
|
||||
platform_port > 0 ? platform_port : 1234;
|
||||
platform_port > 0 ? platform_port : 1234;
|
||||
g_debug_engine->process_base_port =
|
||||
process_port > 0 ? process_port : 6169;
|
||||
process_port > 0 ? process_port : 6169;
|
||||
if (ip_addr)
|
||||
sprintf(g_debug_engine->ip_addr, "%s", ip_addr);
|
||||
else
|
||||
|
@ -277,7 +276,7 @@ static WASMDebugInstance *
|
|||
wasm_cluster_get_debug_instance(WASMDebugEngine *engine, WASMCluster *cluster)
|
||||
{
|
||||
WASMDebugInstance *instance =
|
||||
bh_list_first_elem(&engine->debug_instance_list);
|
||||
bh_list_first_elem(&engine->debug_instance_list);
|
||||
while (instance) {
|
||||
if (instance->cluster == cluster)
|
||||
return instance;
|
||||
|
@ -343,8 +342,7 @@ wasm_debug_instance_get_current_env(WASMDebugInstance *instance)
|
|||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
bool
|
||||
wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
|
||||
char name_buffer[],
|
||||
int len)
|
||||
char name_buffer[], int len)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASIArguments *wasi_args;
|
||||
|
@ -392,8 +390,8 @@ wasm_debug_instance_get_tid(WASMDebugInstance *instance)
|
|||
}
|
||||
|
||||
int
|
||||
wasm_debug_instance_get_tids(WASMDebugInstance *instance,
|
||||
uint64 tids[], int len)
|
||||
wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
|
||||
int len)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
int i = 0;
|
||||
|
@ -411,8 +409,8 @@ wasm_debug_instance_get_tids(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
uint64
|
||||
wasm_debug_instance_wait_thread(WASMDebugInstance *instance,
|
||||
uint64 tid, uint32 *status)
|
||||
wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
|
||||
uint32 *status)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMExecEnv *last_exec_env = NULL;
|
||||
|
@ -454,13 +452,12 @@ wasm_debug_instance_get_pc(WASMDebugInstance *instance)
|
|||
return 0;
|
||||
|
||||
exec_env = wasm_debug_instance_get_current_env(instance);
|
||||
if ((exec_env->cur_frame != NULL)
|
||||
&& (exec_env->cur_frame->ip != NULL)) {
|
||||
if ((exec_env->cur_frame != NULL) && (exec_env->cur_frame->ip != NULL)) {
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
return WASM_ADDR(
|
||||
WasmObj, instance->id,
|
||||
(exec_env->cur_frame->ip - module_inst->module->load_addr));
|
||||
WasmObj, instance->id,
|
||||
(exec_env->cur_frame->ip - module_inst->module->load_addr));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -519,7 +516,8 @@ wasm_debug_instance_get_memregion(WASMDebugInstance *instance, uint64 addr)
|
|||
sprintf(mem_info->permisson, "%s", "rx");
|
||||
}
|
||||
break;
|
||||
case WasmMemory: {
|
||||
case WasmMemory:
|
||||
{
|
||||
memory = module_inst->default_memory;
|
||||
|
||||
if (memory) {
|
||||
|
@ -549,8 +547,8 @@ wasm_debug_instance_destroy_memregion(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
|
||||
uint64 offset, char *buf, uint64 *size)
|
||||
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 offset,
|
||||
char *buf, uint64 *size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
@ -567,14 +565,14 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
|
|||
if (offset + *size > module_inst->module->load_size) {
|
||||
LOG_VERBOSE("wasm_debug_instance_get_data_mem size over flow!\n");
|
||||
*size = module_inst->module->load_size >= offset
|
||||
? module_inst->module->load_size - offset
|
||||
: 0;
|
||||
? module_inst->module->load_size - offset
|
||||
: 0;
|
||||
}
|
||||
|
||||
bh_memcpy_s(buf, *size, module_inst->module->load_addr + offset, *size);
|
||||
|
||||
WASMDebugBreakPoint *breakpoint =
|
||||
bh_list_first_elem(&instance->break_point_list);
|
||||
bh_list_first_elem(&instance->break_point_list);
|
||||
|
||||
while (breakpoint) {
|
||||
if (offset <= breakpoint->addr && breakpoint->addr < offset + *size) {
|
||||
|
@ -585,12 +583,12 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
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) {
|
||||
if (offset <= fast_opcode->offset
|
||||
&& fast_opcode->offset < offset + *size) {
|
||||
*(uint8 *)(buf + (fast_opcode->offset - offset)) =
|
||||
fast_opcode->orig_op;
|
||||
fast_opcode->orig_op;
|
||||
}
|
||||
fast_opcode = bh_list_elem_next(fast_opcode);
|
||||
}
|
||||
|
@ -599,8 +597,8 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
|
||||
uint64 offset, char *buf, uint64 *size)
|
||||
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, uint64 offset,
|
||||
char *buf, uint64 *size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
@ -621,8 +619,7 @@ wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
|
|||
num_bytes_per_page = memory->num_bytes_per_page;
|
||||
linear_mem_size = num_bytes_per_page * memory->cur_page_count;
|
||||
if (offset + *size > linear_mem_size) {
|
||||
LOG_VERBOSE(
|
||||
"wasm_debug_instance_get_linear_mem size over flow!\n");
|
||||
LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
|
||||
*size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
|
||||
}
|
||||
bh_memcpy_s(buf, *size, memory->memory_data + offset, *size);
|
||||
|
@ -632,8 +629,8 @@ wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance,
|
||||
uint64 offset, char *buf, uint64 *size)
|
||||
wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance, uint64 offset,
|
||||
char *buf, uint64 *size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
@ -654,8 +651,7 @@ wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance,
|
|||
num_bytes_per_page = memory->num_bytes_per_page;
|
||||
linear_mem_size = num_bytes_per_page * memory->cur_page_count;
|
||||
if (offset + *size > linear_mem_size) {
|
||||
LOG_VERBOSE(
|
||||
"wasm_debug_instance_get_linear_mem size over flow!\n");
|
||||
LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
|
||||
*size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
|
||||
}
|
||||
bh_memcpy_s(memory->memory_data + offset, *size, buf, *size);
|
||||
|
@ -665,17 +661,17 @@ wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size)
|
||||
wasm_debug_instance_get_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
|
||||
uint64 *size)
|
||||
{
|
||||
switch (WASM_ADDR_TYPE(addr)) {
|
||||
case WasmMemory:
|
||||
return wasm_debug_instance_get_linear_mem(
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
break;
|
||||
case WasmObj:
|
||||
return wasm_debug_instance_get_obj_mem(
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -683,13 +679,13 @@ wasm_debug_instance_get_mem(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_set_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size)
|
||||
wasm_debug_instance_set_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
|
||||
uint64 *size)
|
||||
{
|
||||
switch (WASM_ADDR_TYPE(addr)) {
|
||||
case WasmMemory:
|
||||
return wasm_debug_instance_set_linear_mem(
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
instance, WASM_ADDR_OFFSET(addr), buf, size);
|
||||
break;
|
||||
case WasmObj:
|
||||
default:
|
||||
|
@ -713,8 +709,8 @@ wasm_exec_env_get_instance(WASMExecEnv *exec_env)
|
|||
}
|
||||
|
||||
int
|
||||
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
|
||||
uint64 tid, uint64 buf[], uint64 size)
|
||||
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
|
||||
uint64 buf[], uint64 size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
struct WASMInterpFrame *frame;
|
||||
|
@ -727,13 +723,13 @@ wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
|
|||
while (exec_env) {
|
||||
if (exec_env->handle == tid) {
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
frame = exec_env->cur_frame;
|
||||
while (frame && i < size) {
|
||||
if (frame->ip != NULL) {
|
||||
buf[i++] =
|
||||
WASM_ADDR(WasmObj, instance->id,
|
||||
(frame->ip - module_inst->module->load_addr));
|
||||
WASM_ADDR(WasmObj, instance->id,
|
||||
(frame->ip - module_inst->module->load_addr));
|
||||
}
|
||||
frame = frame->prev_frame;
|
||||
}
|
||||
|
@ -745,8 +741,8 @@ wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
|
||||
uint64 addr, uint64 length)
|
||||
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||
uint64 length)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
@ -769,23 +765,20 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
|
|||
if (offset + sizeof(break_instr) <= module_inst->module->load_size) {
|
||||
WASMDebugBreakPoint *breakpoint;
|
||||
if (!(breakpoint =
|
||||
wasm_runtime_malloc(sizeof(WASMDebugBreakPoint)))) {
|
||||
LOG_ERROR(
|
||||
"WASM Debug Engine error: failed to allocate memory");
|
||||
wasm_runtime_malloc(sizeof(WASMDebugBreakPoint)))) {
|
||||
LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
|
||||
return false;
|
||||
}
|
||||
memset(breakpoint, 0, sizeof(WASMDebugBreakPoint));
|
||||
breakpoint->addr = offset;
|
||||
/* TODO: how to if more than one breakpoints are set
|
||||
at the same addr? */
|
||||
bh_memcpy_s(&breakpoint->orignal_data,
|
||||
(uint32)sizeof(break_instr),
|
||||
bh_memcpy_s(&breakpoint->orignal_data, (uint32)sizeof(break_instr),
|
||||
module_inst->module->load_addr + offset,
|
||||
(uint32)sizeof(break_instr));
|
||||
|
||||
bh_memcpy_s(module_inst->module->load_addr + offset,
|
||||
(uint32)sizeof(break_instr),
|
||||
break_instr,
|
||||
(uint32)sizeof(break_instr), break_instr,
|
||||
(uint32)sizeof(break_instr));
|
||||
|
||||
bh_list_insert(&instance->break_point_list, breakpoint);
|
||||
|
@ -796,8 +789,8 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance,
|
||||
uint64 addr, uint64 length)
|
||||
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||
uint64 length)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
@ -819,10 +812,9 @@ wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance,
|
|||
if (length >= sizeof(break_instr)) {
|
||||
if (offset + sizeof(break_instr) <= module_inst->module->load_size) {
|
||||
WASMDebugBreakPoint *breakpoint =
|
||||
bh_list_first_elem(&instance->break_point_list);
|
||||
bh_list_first_elem(&instance->break_point_list);
|
||||
while (breakpoint) {
|
||||
WASMDebugBreakPoint *next_break =
|
||||
bh_list_elem_next(breakpoint);
|
||||
WASMDebugBreakPoint *next_break = bh_list_elem_next(breakpoint);
|
||||
if (breakpoint->addr == offset) {
|
||||
/* TODO: how to if more than one breakpoints are set
|
||||
at the same addr? */
|
||||
|
@ -901,9 +893,8 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid)
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_local(WASMDebugInstance *instance,
|
||||
int frame_index, int local_index,
|
||||
char buf[], int *size)
|
||||
wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
|
||||
int local_index, char buf[], int *size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
struct WASMInterpFrame *frame;
|
||||
|
@ -961,9 +952,8 @@ wasm_debug_instance_get_local(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_global(WASMDebugInstance *instance,
|
||||
int frame_index, int global_index,
|
||||
char buf[], int *size)
|
||||
wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
|
||||
int global_index, char buf[], int *size)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
struct WASMInterpFrame *frame;
|
||||
|
@ -1003,9 +993,9 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance,
|
|||
global_addr = global_data + global->data_offset;
|
||||
#else
|
||||
global_addr = global->import_global_inst
|
||||
? global->import_module_inst->global_data
|
||||
+ global->import_global_inst->data_offset
|
||||
: global_data + global->data_offset;
|
||||
? global->import_module_inst->global_data
|
||||
+ global->import_global_inst->data_offset
|
||||
: global_data + global->data_offset;
|
||||
#endif
|
||||
global_type = global->type;
|
||||
|
||||
|
@ -1028,8 +1018,7 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance,
|
|||
}
|
||||
|
||||
uint64
|
||||
wasm_debug_instance_mmap(WASMDebugInstance *instance,
|
||||
uint32 size, int map_port)
|
||||
wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size, int map_port)
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
WASMModuleInstance *module_inst;
|
||||
|
|
|
@ -67,10 +67,10 @@ typedef enum WasmAddressType {
|
|||
WasmInvalid = 0x03
|
||||
} WasmAddressType;
|
||||
|
||||
#define WASM_ADDR(type, id, offset) \
|
||||
#define WASM_ADDR(type, id, offset) \
|
||||
(((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 INVALIED_ADDR (0xFFFFFFFFFFFFFFFF)
|
||||
|
@ -96,7 +96,6 @@ wasm_debug_set_engine_active(bool active);
|
|||
bool
|
||||
wasm_debug_get_engine_active(void);
|
||||
|
||||
|
||||
uint64
|
||||
wasm_debug_instance_get_pid(WASMDebugInstance *instance);
|
||||
|
||||
|
@ -104,8 +103,8 @@ uint64
|
|||
wasm_debug_instance_get_tid(WASMDebugInstance *instance);
|
||||
|
||||
int
|
||||
wasm_debug_instance_get_tids(WASMDebugInstance *instance,
|
||||
uint64 tids[], int len);
|
||||
wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
|
||||
int len);
|
||||
|
||||
void
|
||||
wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, uint64 tid);
|
||||
|
@ -124,32 +123,32 @@ wasm_debug_instance_destroy_memregion(WASMDebugInstance *instance,
|
|||
WASMDebugMemoryInfo *mem_info);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size);
|
||||
wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 addr,
|
||||
char *buf, uint64 *size);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size);
|
||||
wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, uint64 addr,
|
||||
char *buf, uint64 *size);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size);
|
||||
wasm_debug_instance_get_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
|
||||
uint64 *size);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_set_mem(WASMDebugInstance *instance,
|
||||
uint64 addr, char *buf, uint64 *size);
|
||||
wasm_debug_instance_set_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
|
||||
uint64 *size);
|
||||
|
||||
int
|
||||
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
|
||||
uint64 tid, uint64 buf[], uint64 size);
|
||||
wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
|
||||
uint64 buf[], uint64 size);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
|
||||
uint64 addr, uint64 length);
|
||||
wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||
uint64 length);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance,
|
||||
uint64 addr, uint64 length);
|
||||
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||
uint64 length);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_continue(WASMDebugInstance *instance);
|
||||
|
@ -158,21 +157,19 @@ bool
|
|||
wasm_debug_instance_kill(WASMDebugInstance *instance);
|
||||
|
||||
uint64
|
||||
wasm_debug_instance_wait_thread(WASMDebugInstance *instance,
|
||||
uint64 tid, uint32 *status);
|
||||
wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
|
||||
uint32 *status);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_local(WASMDebugInstance *instance,
|
||||
int frame_index, int local_index,
|
||||
char buf[], int *size);
|
||||
wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
|
||||
int local_index, char buf[], int *size);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_get_global(WASMDebugInstance *instance,
|
||||
int frame_index, int global_index,
|
||||
char buf[], int *size);
|
||||
wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
|
||||
int global_index, char buf[], int *size);
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
bool
|
||||
|
@ -181,8 +178,8 @@ wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
|
|||
#endif
|
||||
|
||||
uint64
|
||||
wasm_debug_instance_mmap(WASMDebugInstance *instance,
|
||||
uint32 size, int map_port);
|
||||
wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
|
||||
int map_port);
|
||||
|
||||
bool
|
||||
wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr);
|
||||
|
|
|
@ -75,8 +75,9 @@ wasm_launch_gdbserver(char *host, int port)
|
|||
}
|
||||
|
||||
ret = fcntl(listen_fd, F_SETFD, FD_CLOEXEC);
|
||||
if(ret < 0) {
|
||||
LOG_ERROR("wasm gdb server error: fcntl() failed on setting FD_CLOEXEC");
|
||||
if (ret < 0) {
|
||||
LOG_ERROR(
|
||||
"wasm gdb server error: fcntl() failed on setting FD_CLOEXEC");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,13 +55,13 @@ process_xfer(WASMGDBServer *server, const char *name, char *args)
|
|||
*args++ = '\0';
|
||||
|
||||
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(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
char objname[128];
|
||||
wasm_debug_instance_get_current_object_name(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, objname, 128);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, objname, 128);
|
||||
sprintf(tmpbuf,
|
||||
"l<library-list><library name=\"%s\"><section "
|
||||
"address=\"0x%lx\"/></library></library-list>",
|
||||
|
@ -88,8 +88,8 @@ porcess_wasm_local(WASMGDBServer *server, char *args)
|
|||
sprintf(tmpbuf, "E01");
|
||||
if (sscanf(args, "%d;%d", &frame_index, &local_index) == 2) {
|
||||
ret = wasm_debug_instance_get_local(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, frame_index,
|
||||
local_index, buf, &size);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, frame_index,
|
||||
local_index, buf, &size);
|
||||
if (ret && size > 0) {
|
||||
mem2hex(buf, tmpbuf, size);
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ porcess_wasm_global(WASMGDBServer *server, char *args)
|
|||
sprintf(tmpbuf, "E01");
|
||||
if (sscanf(args, "%d;%d", &frame_index, &global_index) == 2) {
|
||||
ret = wasm_debug_instance_get_global(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, frame_index,
|
||||
global_index, buf, &size);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, frame_index,
|
||||
global_index, buf, &size);
|
||||
if (ret && size > 0) {
|
||||
mem2hex(buf, tmpbuf, size);
|
||||
}
|
||||
|
@ -133,14 +133,15 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
if (!strcmp(name, "C")) {
|
||||
uint64_t pid, tid;
|
||||
pid = wasm_debug_instance_get_pid(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
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);
|
||||
write_packet(server, tmpbuf);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -161,10 +162,9 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
}
|
||||
|
||||
if (!strcmp(name, "HostInfo")) {
|
||||
//Todo: change vendor to Intel for outside tree?
|
||||
// Todo: change vendor to Intel for outside tree?
|
||||
char triple[256];
|
||||
mem2hex("wasm32-Ant-wasi-wasm", triple,
|
||||
strlen("wasm32-Ant-wasi-wasm"));
|
||||
mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
|
||||
sprintf(tmpbuf,
|
||||
"vendor:Ant;ostype:wasi;arch:wasm32;"
|
||||
"triple:%s;endian:little;ptrsize:4;",
|
||||
|
@ -183,14 +183,13 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
write_packet(server, "");
|
||||
}
|
||||
if (!strcmp(name, "ProcessInfo")) {
|
||||
//Todo: process id parent-pid
|
||||
// Todo: process id parent-pid
|
||||
uint64_t pid;
|
||||
pid = wasm_debug_instance_get_pid(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
char triple[256];
|
||||
//arch-vendor-os-env(format)
|
||||
mem2hex("wasm32-Ant-wasi-wasm", triple,
|
||||
strlen("wasm32-Ant-wasi-wasm"));
|
||||
// arch-vendor-os-env(format)
|
||||
mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
|
||||
sprintf(tmpbuf,
|
||||
"pid:%lx;parent-pid:%lx;vendor:Ant;ostype:wasi;arch:wasm32;"
|
||||
"triple:%s;endian:little;ptrsize:4;",
|
||||
|
@ -200,9 +199,9 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
}
|
||||
if (!strcmp(name, "RegisterInfo0")) {
|
||||
sprintf(
|
||||
tmpbuf,
|
||||
"name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
|
||||
"set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
|
||||
tmpbuf,
|
||||
"name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
|
||||
"set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
|
||||
write_packet(server, tmpbuf);
|
||||
}
|
||||
else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) {
|
||||
|
@ -215,24 +214,23 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
if (args && (!strcmp(name, "MemoryRegionInfo"))) {
|
||||
uint64_t addr = strtol(args, NULL, 16);
|
||||
WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr);
|
||||
if (mem_info) {
|
||||
char name[256];
|
||||
mem2hex(mem_info->name, name, strlen(mem_info->name));
|
||||
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);
|
||||
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, "WasmMem")) {
|
||||
|
||||
}
|
||||
|
||||
if (!strcmp(name, "Symbol")) {
|
||||
|
@ -243,8 +241,8 @@ handle_generay_query(WASMGDBServer *server, char *payload)
|
|||
uint64_t tid = strtol(args, NULL, 16);
|
||||
uint64_t buf[1024 / sizeof(uint64_t)];
|
||||
uint64_t count = wasm_debug_instance_get_call_stack_pcs(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid, buf,
|
||||
1024 / sizeof(uint64_t));
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid, buf,
|
||||
1024 / sizeof(uint64_t));
|
||||
if (count > 0) {
|
||||
mem2hex((char *)buf, tmpbuf, count * sizeof(uint64_t));
|
||||
write_packet(server, tmpbuf);
|
||||
|
@ -276,16 +274,17 @@ send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
|
|||
return;
|
||||
}
|
||||
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(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
|
||||
if (status == WAMR_SIG_SINGSTEP) {
|
||||
gdb_status = WAMR_SIG_TRAP;
|
||||
}
|
||||
|
||||
//TODO: how name a wasm thread?
|
||||
len += sprintf(tmpbuf, "T%02xthread:%lx;name:%s;", gdb_status, tid, "nobody");
|
||||
// TODO: how name a wasm thread?
|
||||
len +=
|
||||
sprintf(tmpbuf, "T%02xthread:%lx;name:%s;", gdb_status, tid, "nobody");
|
||||
if (tids_number > 0) {
|
||||
len += sprintf(tmpbuf + len, "threads:");
|
||||
while (i < tids_number) {
|
||||
|
@ -336,12 +335,12 @@ handle_v_packet(WASMGDBServer *server, char *payload)
|
|||
*numstring++ = '\0';
|
||||
uint64_t tid = strtol(numstring, NULL, 16);
|
||||
wasm_debug_instance_set_cur_thread(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
wasm_debug_instance_singlestep(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -352,11 +351,11 @@ void
|
|||
handle_threadstop_request(WASMGDBServer *server, char *payload)
|
||||
{
|
||||
uint64_t tid = wasm_debug_instance_get_tid(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
uint32_t status;
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -370,7 +369,7 @@ handle_set_current_thread(WASMGDBServer *server, char *payload)
|
|||
tid = strtol(payload, NULL, 16);
|
||||
if (tid > 0)
|
||||
wasm_debug_instance_set_cur_thread(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, tid);
|
||||
}
|
||||
write_packet(server, "OK");
|
||||
}
|
||||
|
@ -385,7 +384,7 @@ handle_get_register(WASMGDBServer *server, char *payload)
|
|||
return;
|
||||
}
|
||||
uint64_t regdata = wasm_debug_instance_get_pc(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
mem2hex((void *)®data, tmpbuf, 8);
|
||||
tmpbuf[8 * 2] = '\0';
|
||||
write_packet(server, tmpbuf);
|
||||
|
@ -423,8 +422,8 @@ handle_get_read_memory(WASMGDBServer *server, char *payload)
|
|||
char *buff = wasm_runtime_malloc(mlen);
|
||||
if (buff) {
|
||||
ret = wasm_debug_instance_get_mem(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, maddr, buff,
|
||||
&mlen);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, maddr,
|
||||
buff, &mlen);
|
||||
if (ret) {
|
||||
mem2hex(buff, tmpbuf, mlen);
|
||||
}
|
||||
|
@ -451,8 +450,8 @@ handle_get_write_memory(WASMGDBServer *server, char *payload)
|
|||
if (buff) {
|
||||
hex2mem(payload, buff, act_len);
|
||||
ret = wasm_debug_instance_set_mem(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, maddr, buff,
|
||||
&mlen);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, maddr,
|
||||
buff, &mlen);
|
||||
if (ret) {
|
||||
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 (type == eBreakpointSoftware) {
|
||||
bool ret = wasm_debug_instance_add_breakpoint(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
||||
length);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
||||
length);
|
||||
if (ret)
|
||||
write_packet(server, "OK");
|
||||
else
|
||||
|
@ -490,8 +489,8 @@ handle_remove_break(WASMGDBServer *server, char *payload)
|
|||
if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) {
|
||||
if (type == eBreakpointSoftware) {
|
||||
bool ret = wasm_debug_instance_remove_breakpoint(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
||||
length);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
||||
length);
|
||||
if (ret)
|
||||
write_packet(server, "OK");
|
||||
else
|
||||
|
@ -509,13 +508,13 @@ handle_continue_request(WASMGDBServer *server, char *payload)
|
|||
uint32_t status;
|
||||
|
||||
wasm_debug_instance_continue(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
|
||||
tid = wasm_debug_instance_get_tid(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -527,13 +526,13 @@ handle_kill_request(WASMGDBServer *server, char *payload)
|
|||
uint32_t status;
|
||||
|
||||
wasm_debug_instance_kill(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
|
||||
tid = wasm_debug_instance_get_tid(
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
(WASMDebugInstance *)server->thread->debug_instance);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -572,7 +571,8 @@ handle_malloc(WASMGDBServer *server, char *payload)
|
|||
args++;
|
||||
}
|
||||
addr = wasm_debug_instance_mmap(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, size, map_port);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, size,
|
||||
map_port);
|
||||
if (addr) {
|
||||
sprintf(tmpbuf, "%lx", addr);
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ handle_free(WASMGDBServer *server, char *payload)
|
|||
addr = strtol(payload, NULL, 16);
|
||||
|
||||
ret = wasm_debug_instance_ummap(
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr);
|
||||
(WASMDebugInstance *)server->thread->debug_instance, addr);
|
||||
if (ret) {
|
||||
sprintf(tmpbuf, "%s", "OK");
|
||||
}
|
||||
|
|
|
@ -83,8 +83,7 @@ write_hex(WASMGDBServer *gdbserver, unsigned long hex)
|
|||
}
|
||||
|
||||
void
|
||||
write_packet_bytes(WASMGDBServer *gdbserver,
|
||||
const uint8_t *data,
|
||||
write_packet_bytes(WASMGDBServer *gdbserver, const uint8_t *data,
|
||||
size_t num_bytes)
|
||||
{
|
||||
uint8_t checksum;
|
||||
|
@ -106,10 +105,8 @@ write_packet(WASMGDBServer *gdbserver, const char *data)
|
|||
}
|
||||
|
||||
void
|
||||
write_binary_packet(WASMGDBServer *gdbserver,
|
||||
const char *pfx,
|
||||
const uint8_t *data,
|
||||
ssize_t num_bytes)
|
||||
write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
|
||||
const uint8_t *data, ssize_t num_bytes)
|
||||
{
|
||||
uint8_t *buf;
|
||||
ssize_t pfx_num_chars = strlen(pfx);
|
||||
|
|
|
@ -12,13 +12,14 @@
|
|||
|
||||
#define WAMR_PTHREAD_KEYS_MAX 32
|
||||
|
||||
/* clang-format off */
|
||||
#define get_module(exec_env) \
|
||||
wasm_exec_env_get_module(exec_env)
|
||||
|
||||
#define 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)
|
||||
|
||||
#define get_wasi_ctx(module_inst) \
|
||||
|
@ -35,10 +36,10 @@
|
|||
|
||||
#define addr_native_to_app(ptr) \
|
||||
wasm_runtime_addr_native_to_app(module_inst, ptr)
|
||||
/* clang-format on */
|
||||
|
||||
extern bool
|
||||
wasm_runtime_call_indirect(wasm_exec_env_t exec_env,
|
||||
uint32 element_indices,
|
||||
wasm_runtime_call_indirect(wasm_exec_env_t exec_env, uint32 element_indices,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
enum {
|
||||
|
@ -95,7 +96,7 @@ typedef struct ThreadInfoNode {
|
|||
/* type can be [THREAD | MUTEX | CONDITION] */
|
||||
uint32 type;
|
||||
/* 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;
|
||||
bool joinable;
|
||||
union {
|
||||
|
@ -161,8 +162,7 @@ lib_pthread_init()
|
|||
if (0 != os_mutex_init(&thread_global_lock))
|
||||
return false;
|
||||
bh_list_init(&cluster_info_list);
|
||||
if (!wasm_cluster_register_destroy_callback(
|
||||
lib_pthread_destroy_callback)) {
|
||||
if (!wasm_cluster_register_destroy_callback(lib_pthread_destroy_callback)) {
|
||||
os_mutex_destroy(&thread_global_lock);
|
||||
return false;
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ lib_pthread_destroy()
|
|||
os_mutex_destroy(&thread_global_lock);
|
||||
}
|
||||
|
||||
static ClusterInfoNode*
|
||||
static ClusterInfoNode *
|
||||
get_cluster_info(WASMCluster *cluster)
|
||||
{
|
||||
ClusterInfoNode *node;
|
||||
|
@ -195,30 +195,30 @@ get_cluster_info(WASMCluster *cluster)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static KeyData*
|
||||
static KeyData *
|
||||
key_data_list_lookup(wasm_exec_env_t exec_env, int32 key)
|
||||
{
|
||||
ClusterInfoNode *node;
|
||||
WASMCluster *cluster =
|
||||
wasm_exec_env_get_cluster(exec_env);
|
||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
|
||||
if ((node = get_cluster_info(cluster))) {
|
||||
return (key >= 0 && key < WAMR_PTHREAD_KEYS_MAX
|
||||
&& node->key_data_list[key].is_created)
|
||||
? &(node->key_data_list[key]) : NULL;
|
||||
? &(node->key_data_list[key])
|
||||
: NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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
|
||||
the local storage, it will not occupy memory space
|
||||
*/
|
||||
static int32*
|
||||
key_value_list_lookup_or_create(wasm_exec_env_t exec_env,
|
||||
ClusterInfoNode *info, int32 key)
|
||||
/**
|
||||
* 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 the
|
||||
* local storage, it will not occupy memory space.
|
||||
*/
|
||||
static int32 *
|
||||
key_value_list_lookup_or_create(wasm_exec_env_t exec_env, ClusterInfoNode *info,
|
||||
int32 key)
|
||||
{
|
||||
KeyData *key_node;
|
||||
ThreadKeyValueNode *data;
|
||||
|
@ -296,9 +296,7 @@ call_key_destructor(wasm_exec_env_t exec_env)
|
|||
uint32 argv[1];
|
||||
|
||||
argv[0] = value;
|
||||
wasm_runtime_call_indirect(exec_env,
|
||||
destructor_index,
|
||||
1, argv);
|
||||
wasm_runtime_call_indirect(exec_env, 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)
|
||||
{
|
||||
ClusterInfoNode *node;
|
||||
|
@ -346,12 +344,9 @@ create_cluster_info(WASMCluster *cluster)
|
|||
}
|
||||
|
||||
node->cluster = cluster;
|
||||
if (!(node->thread_info_map =
|
||||
bh_hash_map_create(32, true,
|
||||
(HashFunc)thread_handle_hash,
|
||||
(KeyEqualFunc)thread_handle_equal,
|
||||
NULL,
|
||||
thread_info_destroy))) {
|
||||
if (!(node->thread_info_map = bh_hash_map_create(
|
||||
32, true, (HashFunc)thread_handle_hash,
|
||||
(KeyEqualFunc)thread_handle_equal, NULL, thread_info_destroy))) {
|
||||
os_mutex_destroy(&node->key_data_list_lock);
|
||||
wasm_runtime_free(node);
|
||||
return NULL;
|
||||
|
@ -395,13 +390,12 @@ delete_thread_info_node(ThreadInfoNode *thread_info)
|
|||
{
|
||||
ClusterInfoNode *node;
|
||||
bool ret;
|
||||
WASMCluster *cluster =
|
||||
wasm_exec_env_get_cluster(thread_info->exec_env);
|
||||
WASMCluster *cluster = wasm_exec_env_get_cluster(thread_info->exec_env);
|
||||
|
||||
if ((node = get_cluster_info(cluster))) {
|
||||
ret = bh_hash_map_remove(node->thread_info_map,
|
||||
(void *)(uintptr_t)thread_info->handle,
|
||||
NULL, NULL);
|
||||
(void *)(uintptr_t)thread_info->handle, NULL,
|
||||
NULL);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
|
@ -412,8 +406,7 @@ static bool
|
|||
append_thread_info_node(ThreadInfoNode *thread_info)
|
||||
{
|
||||
ClusterInfoNode *node;
|
||||
WASMCluster *cluster =
|
||||
wasm_exec_env_get_cluster(thread_info->exec_env);
|
||||
WASMCluster *cluster = wasm_exec_env_get_cluster(thread_info->exec_env);
|
||||
|
||||
if (!(node = get_cluster_info(cluster))) {
|
||||
if (!(node = create_cluster_info(cluster))) {
|
||||
|
@ -430,7 +423,7 @@ append_thread_info_node(ThreadInfoNode *thread_info)
|
|||
return true;
|
||||
}
|
||||
|
||||
static ThreadInfoNode*
|
||||
static ThreadInfoNode *
|
||||
get_thread_info(wasm_exec_env_t exec_env, uint32 handle)
|
||||
{
|
||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
|
@ -453,7 +446,7 @@ allocate_handle()
|
|||
return id;
|
||||
}
|
||||
|
||||
static void*
|
||||
static void *
|
||||
pthread_start_routine(void *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);
|
||||
argv[0] = routine_args->arg;
|
||||
|
||||
if(!wasm_runtime_call_indirect(exec_env,
|
||||
routine_args->elem_index,
|
||||
1, argv)) {
|
||||
if (!wasm_runtime_call_indirect(exec_env, routine_args->elem_index, 1,
|
||||
argv)) {
|
||||
if (wasm_runtime_get_exception(module_inst))
|
||||
wasm_cluster_spread_exception(exec_env);
|
||||
}
|
||||
|
@ -498,8 +490,8 @@ pthread_start_routine(void *arg)
|
|||
wasm_runtime_free(routine_args);
|
||||
|
||||
/* if the thread is joinable, store the result in its info node,
|
||||
if the other threads join this thread after exited, then we
|
||||
can return the stored result */
|
||||
if the other threads join this thread after exited, then we
|
||||
can return the stored result */
|
||||
if (!info_node->joinable) {
|
||||
delete_thread_info_node(info_node);
|
||||
}
|
||||
|
@ -520,10 +512,10 @@ pthread_start_routine(void *arg)
|
|||
|
||||
static int
|
||||
pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 *thread, /* thread_handle */
|
||||
const void *attr, /* not supported */
|
||||
uint32 elem_index, /* entry function */
|
||||
uint32 arg) /* arguments buffer */
|
||||
uint32 *thread, /* thread_handle */
|
||||
const void *attr, /* not supported */
|
||||
uint32 elem_index, /* entry function */
|
||||
uint32 arg) /* arguments buffer */
|
||||
{
|
||||
wasm_module_t module = get_module(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_inst);
|
||||
|
||||
if (!(new_module_inst =
|
||||
wasm_runtime_instantiate_internal(module, true, 8192, 0,
|
||||
NULL, 0)))
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, true, 8192, 0, NULL, 0)))
|
||||
return -1;
|
||||
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst,
|
||||
wasm_runtime_get_custom_data(module_inst));
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
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;
|
||||
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
ret = wasm_cluster_create_thread(exec_env, new_module_inst,
|
||||
pthread_start_routine,
|
||||
(void *)routine_args);
|
||||
ret = wasm_cluster_create_thread(
|
||||
exec_env, new_module_inst, pthread_start_routine, (void *)routine_args);
|
||||
if (ret != 0) {
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Wait for the thread routine to assign the exec_env to
|
||||
thread_info_node, otherwise the exec_env in the thread
|
||||
info node may be NULL in the next pthread API call */
|
||||
thread_info_node, otherwise the exec_env in the thread
|
||||
info node may be NULL in the next pthread API call */
|
||||
os_cond_wait(&exec_env->wait_cond, &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);
|
||||
|
||||
/* 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))) {
|
||||
/* 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);
|
||||
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 */
|
||||
|
||||
/* 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);
|
||||
join_ret = 0;
|
||||
ret = node->u.ret;
|
||||
}
|
||||
|
||||
if (retval_offset != 0)
|
||||
*(uint32*)retval = (uint32)(uintptr_t)ret;
|
||||
*(uint32 *)retval = (uint32)(uintptr_t)ret;
|
||||
|
||||
return join_ret;
|
||||
}
|
||||
|
@ -699,7 +688,7 @@ pthread_self_wrapper(wasm_exec_env_t exec_env)
|
|||
{
|
||||
ThreadRoutineArgs *args = get_thread_arg(exec_env);
|
||||
/* 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)
|
||||
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 hardware bound check enabled, don't deinstantiate module inst
|
||||
and thread info node here for AoT module, as they will be freed
|
||||
in pthread_start_routine */
|
||||
and thread info node here for AoT module, as they will be freed
|
||||
in pthread_start_routine */
|
||||
if (exec_env->jmpbuf_stack_top) {
|
||||
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 */
|
||||
if (mutex)
|
||||
*(uint32*)mutex = info_node->handle;
|
||||
*(uint32 *)mutex = info_node->handle;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -790,7 +779,7 @@ fail1:
|
|||
static int32
|
||||
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)
|
||||
return -1;
|
||||
|
||||
|
@ -800,7 +789,7 @@ pthread_mutex_lock_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
|
|||
static int32
|
||||
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)
|
||||
return -1;
|
||||
|
||||
|
@ -811,7 +800,7 @@ static int32
|
|||
pthread_mutex_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *mutex)
|
||||
{
|
||||
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)
|
||||
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 */
|
||||
if (cond)
|
||||
*(uint32*)cond = info_node->handle;
|
||||
*(uint32 *)cond = info_node->handle;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond,
|
||||
uint32 *mutex, uint64 useconds)
|
||||
|
@ -906,7 +896,7 @@ pthread_cond_timedwait_wrapper(wasm_exec_env_t exec_env, uint32 *cond,
|
|||
static int32
|
||||
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)
|
||||
return -1;
|
||||
|
||||
|
@ -917,7 +907,7 @@ static int32
|
|||
pthread_cond_destroy_wrapper(wasm_exec_env_t exec_env, uint32 *cond)
|
||||
{
|
||||
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)
|
||||
return -1;
|
||||
|
||||
|
@ -939,7 +929,7 @@ pthread_key_create_wrapper(wasm_exec_env_t exec_env, int32 *key,
|
|||
|
||||
if (!info) {
|
||||
/* 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))) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1037,46 +1027,50 @@ pthread_key_delete_wrapper(wasm_exec_env_t exec_env, int32 key)
|
|||
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
|
||||
posix_memalign_wrapper(wasm_exec_env_t exec_env,
|
||||
void **memptr, int32 align, int32 size)
|
||||
posix_memalign_wrapper(wasm_exec_env_t exec_env, void **memptr, int32 align,
|
||||
int32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
void *p = NULL;
|
||||
|
||||
*((int32 *)memptr) = module_malloc(size, (void**)&p);
|
||||
*((int32 *)memptr) = module_malloc(size, (void **)&p);
|
||||
if (!p)
|
||||
return -1;
|
||||
|
||||
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 }
|
||||
/* clang-format on */
|
||||
|
||||
static NativeSymbol native_symbols_lib_pthread[] = {
|
||||
REG_NATIVE_FUNC(pthread_create, "(**ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_join, "(ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_detach, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_cancel, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_self, "()i"),
|
||||
REG_NATIVE_FUNC(pthread_exit, "(i)"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_init, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_lock, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_unlock, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_init, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_wait, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_create, "(**ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_join, "(ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_detach, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_cancel, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_self, "()i"),
|
||||
REG_NATIVE_FUNC(pthread_exit, "(i)"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_init, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_lock, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_unlock, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_mutex_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_init, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_wait, "(**)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_timedwait, "(**I)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_signal, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_create, "(*i)i"),
|
||||
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
|
||||
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_signal, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_cond_destroy, "(*)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_create, "(*i)i"),
|
||||
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
|
||||
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
|
||||
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
|
||||
};
|
||||
|
||||
uint32
|
||||
|
|
|
@ -29,9 +29,10 @@ void
|
|||
wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack);
|
||||
|
||||
uint32
|
||||
wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr,
|
||||
uint32 size, void **p_native_addr);
|
||||
wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, uint32 size,
|
||||
void **p_native_addr);
|
||||
|
||||
/* clang-format off */
|
||||
#define 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) \
|
||||
wasm_runtime_module_free(module_inst, offset)
|
||||
/* clang-format on */
|
||||
|
||||
typedef int (*out_func_t)(int c, void *ctx);
|
||||
|
||||
|
@ -66,15 +68,14 @@ enum pad_type {
|
|||
};
|
||||
|
||||
typedef char *_va_list;
|
||||
#define _INTSIZEOF(n) \
|
||||
(((uint32)sizeof(n) + 3) & (uint32)~3)
|
||||
#define _va_arg(ap, t) \
|
||||
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
|
||||
#define _INTSIZEOF(n) (((uint32)sizeof(n) + 3) & (uint32)~3)
|
||||
#define _va_arg(ap, t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
|
||||
|
||||
#define CHECK_VA_ARG(ap, t) do { \
|
||||
if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
#define CHECK_VA_ARG(ap, t) \
|
||||
do { \
|
||||
if ((uint8 *)ap + _INTSIZEOF(t) > native_end_addr) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Output an unsigned int in hex format
|
||||
|
@ -86,10 +87,8 @@ typedef char *_va_list;
|
|||
* @return N/A
|
||||
*/
|
||||
static void
|
||||
_printf_hex_uint(out_func_t out, void *ctx,
|
||||
const uint64 num, bool is_u64,
|
||||
enum pad_type padding,
|
||||
int min_width)
|
||||
_printf_hex_uint(out_func_t out, void *ctx, const uint64 num, bool is_u64,
|
||||
enum pad_type padding, int min_width)
|
||||
{
|
||||
int shift = sizeof(num) * 8;
|
||||
int found_largest_digit = 0;
|
||||
|
@ -97,14 +96,14 @@ _printf_hex_uint(out_func_t out, void *ctx,
|
|||
int digits = 0;
|
||||
char nibble;
|
||||
|
||||
while (shift >= 4) {
|
||||
shift -= 4;
|
||||
nibble = (num >> shift) & 0xf;
|
||||
while (shift >= 4) {
|
||||
shift -= 4;
|
||||
nibble = (num >> shift) & 0xf;
|
||||
|
||||
if (nibble || found_largest_digit || shift == 0) {
|
||||
found_largest_digit = 1;
|
||||
nibble = (char)(nibble + (nibble > 9 ? 87 : 48));
|
||||
out((int) nibble, ctx);
|
||||
out((int)nibble, ctx);
|
||||
digits++;
|
||||
continue;
|
||||
}
|
||||
|
@ -112,7 +111,8 @@ _printf_hex_uint(out_func_t out, void *ctx,
|
|||
if (remaining-- <= min_width) {
|
||||
if (padding == PAD_ZERO_BEFORE) {
|
||||
out('0', ctx);
|
||||
} else if (padding == PAD_SPACE_BEFORE) {
|
||||
}
|
||||
else if (padding == PAD_SPACE_BEFORE) {
|
||||
out(' ', ctx);
|
||||
}
|
||||
}
|
||||
|
@ -136,10 +136,8 @@ _printf_hex_uint(out_func_t out, void *ctx,
|
|||
* @return N/A
|
||||
*/
|
||||
static void
|
||||
_printf_dec_uint(out_func_t out, void *ctx,
|
||||
const uint32 num,
|
||||
enum pad_type padding,
|
||||
int min_width)
|
||||
_printf_dec_uint(out_func_t out, void *ctx, const uint32 num,
|
||||
enum pad_type padding, int min_width)
|
||||
{
|
||||
uint32 pos = 999999999;
|
||||
uint32 remainder = num;
|
||||
|
@ -155,17 +153,18 @@ _printf_dec_uint(out_func_t out, void *ctx,
|
|||
while (pos >= 9) {
|
||||
if (found_largest_digit || remainder > pos) {
|
||||
found_largest_digit = 1;
|
||||
out((int) ((remainder / (pos + 1)) + 48), ctx);
|
||||
out((int)((remainder / (pos + 1)) + 48), ctx);
|
||||
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++;
|
||||
}
|
||||
remaining--;
|
||||
remainder %= (pos + 1);
|
||||
pos /= 10;
|
||||
}
|
||||
out((int) (remainder + 48), ctx);
|
||||
out((int)(remainder + 48), ctx);
|
||||
|
||||
if (padding == PAD_SPACE_AFTER) {
|
||||
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;
|
||||
uint8 *native_end_addr;
|
||||
|
||||
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap,
|
||||
NULL, &native_end_addr))
|
||||
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)ap, NULL,
|
||||
&native_end_addr))
|
||||
goto fail;
|
||||
|
||||
/* 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) {
|
||||
if (!might_format) {
|
||||
if (*fmt != '%') {
|
||||
out((int) *fmt, ctx);
|
||||
out((int)*fmt, ctx);
|
||||
}
|
||||
else {
|
||||
might_format = 1;
|
||||
|
@ -213,179 +212,188 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
|
|||
}
|
||||
else {
|
||||
switch (*fmt) {
|
||||
case '-':
|
||||
padding = PAD_SPACE_AFTER;
|
||||
goto still_might_format;
|
||||
|
||||
case '0':
|
||||
if (min_width < 0 && padding == PAD_NONE) {
|
||||
padding = PAD_ZERO_BEFORE;
|
||||
case '-':
|
||||
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 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 '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';
|
||||
case 'u':
|
||||
{
|
||||
uint32 u;
|
||||
|
||||
if (long_ctr < 2) {
|
||||
CHECK_VA_ARG(ap, uint32);
|
||||
u = _va_arg(ap, uint32);
|
||||
}
|
||||
else {
|
||||
uint64 llu;
|
||||
CHECK_VA_ARG(ap, uint64);
|
||||
llu = _va_arg(ap, uint64);
|
||||
if (llu > INT32_MAX) {
|
||||
print_err(out, ctx);
|
||||
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) {
|
||||
padding = PAD_SPACE_BEFORE;
|
||||
}
|
||||
goto still_might_format;
|
||||
case 's':
|
||||
{
|
||||
char *s;
|
||||
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);
|
||||
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;
|
||||
s_offset = _va_arg(ap, uint32);
|
||||
|
||||
if (!validate_app_str_addr(s_offset)) {
|
||||
return false;
|
||||
}
|
||||
d = (int32)lld;
|
||||
}
|
||||
|
||||
if (d < 0) {
|
||||
out((int)'-', ctx);
|
||||
d = -d;
|
||||
min_width--;
|
||||
}
|
||||
_printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
uint32 u;
|
||||
s = start = addr_app_to_native(s_offset);
|
||||
|
||||
if (long_ctr < 2) {
|
||||
CHECK_VA_ARG(ap, uint32);
|
||||
u = _va_arg(ap, uint32);
|
||||
}
|
||||
else {
|
||||
uint64 llu;
|
||||
CHECK_VA_ARG(ap, uint64);
|
||||
llu = _va_arg(ap, uint64);
|
||||
if (llu > INT32_MAX) {
|
||||
print_err(out, ctx);
|
||||
break;
|
||||
while (*s)
|
||||
out((int)(*s++), ctx);
|
||||
|
||||
if (padding == PAD_SPACE_AFTER) {
|
||||
int remaining = min_width - (int32)(s - start);
|
||||
while (remaining-- > 0) {
|
||||
out(' ', ctx);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
s = start = addr_app_to_native(s_offset);
|
||||
|
||||
while (*s)
|
||||
out((int) (*s++), ctx);
|
||||
|
||||
if (padding == PAD_SPACE_AFTER) {
|
||||
int remaining = min_width - (int32)(s - start);
|
||||
while (remaining-- > 0) {
|
||||
out(' ', ctx);
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
int c;
|
||||
CHECK_VA_ARG(ap, int);
|
||||
c = _va_arg(ap, int);
|
||||
out(c, ctx);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': {
|
||||
int c;
|
||||
CHECK_VA_ARG(ap, int);
|
||||
c = _va_arg(ap, int);
|
||||
out(c, ctx);
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
{
|
||||
out((int)'%', ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
case '%': {
|
||||
out((int) '%', ctx);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
float64 f64;
|
||||
char buf[16], *s;
|
||||
|
||||
case 'f': {
|
||||
float64 f64;
|
||||
char buf[16], *s;
|
||||
/* Make 8-byte aligned */
|
||||
ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7);
|
||||
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 */
|
||||
ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7);
|
||||
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;
|
||||
}
|
||||
|
||||
default:
|
||||
out((int) '%', ctx);
|
||||
out((int) *fmt, ctx);
|
||||
break;
|
||||
default:
|
||||
out((int)'%', ctx);
|
||||
out((int)*fmt, ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
might_format = 0;
|
||||
}
|
||||
|
||||
still_might_format:
|
||||
still_might_format:
|
||||
++fmt;
|
||||
}
|
||||
return true;
|
||||
|
@ -411,7 +419,8 @@ sprintf_out(int c, struct str_context *ctx)
|
|||
|
||||
if (ctx->count == ctx->max - 1) {
|
||||
ctx->str[ctx->count++] = '\0';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ctx->str[ctx->count++] = (char)c;
|
||||
}
|
||||
|
||||
|
@ -453,8 +462,7 @@ printf_out(int c, struct str_context *ctx)
|
|||
#endif
|
||||
|
||||
static int
|
||||
printf_wrapper(wasm_exec_env_t exec_env,
|
||||
const char * format, _va_list va_args)
|
||||
printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
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 (int)ctx.count;
|
||||
}
|
||||
|
||||
static int
|
||||
sprintf_wrapper(wasm_exec_env_t exec_env,
|
||||
char *str, const char *format, _va_list va_args)
|
||||
sprintf_wrapper(wasm_exec_env_t exec_env, char *str, const char *format,
|
||||
_va_list va_args)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint8 *native_end_offset;
|
||||
|
@ -481,17 +490,18 @@ sprintf_wrapper(wasm_exec_env_t exec_env,
|
|||
if (!validate_native_addr(va_args, sizeof(uint32)))
|
||||
return 0;
|
||||
|
||||
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)str,
|
||||
NULL, &native_end_offset)) {
|
||||
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)str, NULL,
|
||||
&native_end_offset)) {
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx.str = str;
|
||||
ctx.max = (uint32)(native_end_offset - (uint8*)str);
|
||||
ctx.max = (uint32)(native_end_offset - (uint8 *)str);
|
||||
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;
|
||||
|
||||
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.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;
|
||||
|
||||
if (ctx.count < ctx.max) {
|
||||
|
@ -551,7 +562,7 @@ strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
|
|||
if (str) {
|
||||
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) {
|
||||
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
|
||||
memcmp_wrapper(wasm_exec_env_t exec_env,
|
||||
const void *s1, const void *s2, uint32 size)
|
||||
memcmp_wrapper(wasm_exec_env_t exec_env, const void *s1, const void *s2,
|
||||
uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
/* s2 has been checked by runtime */
|
||||
if (!validate_native_addr((void*)s1, size))
|
||||
if (!validate_native_addr((void *)s1, size))
|
||||
return 0;
|
||||
|
||||
return memcmp(s1, s2, size);
|
||||
}
|
||||
|
||||
static uint32
|
||||
memcpy_wrapper(wasm_exec_env_t exec_env,
|
||||
void *dst, const void *src, uint32 size)
|
||||
memcpy_wrapper(wasm_exec_env_t exec_env, void *dst, const void *src,
|
||||
uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 dst_offset = addr_native_to_app(dst);
|
||||
|
@ -598,8 +609,7 @@ memcpy_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
memmove_wrapper(wasm_exec_env_t exec_env,
|
||||
void *dst, void *src, uint32 size)
|
||||
memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 dst_offset = addr_native_to_app(dst);
|
||||
|
@ -616,8 +626,7 @@ memmove_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
memset_wrapper(wasm_exec_env_t exec_env,
|
||||
void *s, int32 c, uint32 size)
|
||||
memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 s_offset = addr_native_to_app(s);
|
||||
|
@ -630,8 +639,7 @@ memset_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
strchr_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s, int32 c)
|
||||
strchr_wrapper(wasm_exec_env_t exec_env, const char *s, int32 c)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
char *ret;
|
||||
|
@ -642,21 +650,20 @@ strchr_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int32
|
||||
strcmp_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s1, const char *s2)
|
||||
strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2)
|
||||
{
|
||||
/* s1 and s2 have been checked by runtime */
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
static int32
|
||||
strncmp_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s1, const char *s2, uint32 size)
|
||||
strncmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
|
||||
uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
/* s2 has been checked by runtime */
|
||||
if (!validate_native_addr((void*)s1, size))
|
||||
if (!validate_native_addr((void *)s1, size))
|
||||
return 0;
|
||||
|
||||
return strncmp(s1, s2, size);
|
||||
|
@ -681,8 +688,8 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
|
|||
}
|
||||
|
||||
static uint32
|
||||
strncpy_wrapper(wasm_exec_env_t exec_env,
|
||||
char *dst, const char *src, uint32 size)
|
||||
strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
|
||||
uint32 size)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
uint8 *ret_ptr;
|
||||
|
||||
if (total_size >= UINT32_MAX)
|
||||
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) {
|
||||
memset(ret_ptr, 0, (uint32)total_size);
|
||||
}
|
||||
|
@ -767,8 +774,8 @@ exit_wrapper(wasm_exec_env_t exec_env, int32 status)
|
|||
}
|
||||
|
||||
static int32
|
||||
strtol_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *nptr, char **endptr, int32 base)
|
||||
strtol_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
|
||||
int32 base)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
int32 num = 0;
|
||||
|
@ -778,14 +785,14 @@ strtol_wrapper(wasm_exec_env_t exec_env,
|
|||
return 0;
|
||||
|
||||
num = (int32)strtol(nptr, endptr, base);
|
||||
*(uint32*)endptr = addr_native_to_app(*endptr);
|
||||
*(uint32 *)endptr = addr_native_to_app(*endptr);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32
|
||||
strtoul_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *nptr, char **endptr, int32 base)
|
||||
strtoul_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
|
||||
int32 base)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 num = 0;
|
||||
|
@ -801,13 +808,12 @@ strtoul_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
memchr_wrapper(wasm_exec_env_t exec_env,
|
||||
const void *s, int32 c, uint32 n)
|
||||
memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
void *res;
|
||||
|
||||
if (!validate_native_addr((void*)s, n))
|
||||
if (!validate_native_addr((void *)s, n))
|
||||
return 0;
|
||||
|
||||
res = memchr(s, c, n);
|
||||
|
@ -815,32 +821,29 @@ memchr_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int32
|
||||
strncasecmp_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s1, const char *s2, uint32 n)
|
||||
strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
|
||||
uint32 n)
|
||||
{
|
||||
/* s1 and s2 have been checked by runtime */
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
||||
static uint32
|
||||
strspn_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s, const char *accept)
|
||||
strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
|
||||
{
|
||||
/* s and accept have been checked by runtime */
|
||||
return (uint32)strspn(s, accept);
|
||||
}
|
||||
|
||||
static uint32
|
||||
strcspn_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s, const char *reject)
|
||||
strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject)
|
||||
{
|
||||
/* s and reject have been checked by runtime */
|
||||
return (uint32)strcspn(s, reject);
|
||||
}
|
||||
|
||||
static uint32
|
||||
strstr_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *s, const char *find)
|
||||
strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
/* s and find have been checked by runtime */
|
||||
|
@ -925,24 +928,19 @@ getTempRet0_wrapper(wasm_exec_env_t exec_env)
|
|||
static uint32
|
||||
llvm_bswap_i16_wrapper(wasm_exec_env_t exec_env, uint32 data)
|
||||
{
|
||||
return (data & 0xFFFF0000)
|
||||
| ((data & 0xFF) << 8)
|
||||
| ((data & 0xFF00) >> 8);
|
||||
return (data & 0xFFFF0000) | ((data & 0xFF) << 8) | ((data & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
static uint32
|
||||
llvm_bswap_i32_wrapper(wasm_exec_env_t exec_env, uint32 data)
|
||||
{
|
||||
return ((data & 0xFF) << 24)
|
||||
| ((data & 0xFF00) << 8)
|
||||
| ((data & 0xFF0000) >> 8)
|
||||
| ((data & 0xFF000000) >> 24);
|
||||
return ((data & 0xFF) << 24) | ((data & 0xFF00) << 8)
|
||||
| ((data & 0xFF0000) >> 8) | ((data & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
static uint32
|
||||
bitshift64Lshr_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 uint64_part0, uint32 uint64_part1,
|
||||
uint32 bits)
|
||||
bitshift64Lshr_wrapper(wasm_exec_env_t exec_env, uint32 uint64_part0,
|
||||
uint32 uint64_part1, uint32 bits)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
union {
|
||||
|
@ -955,14 +953,13 @@ bitshift64Lshr_wrapper(wasm_exec_env_t exec_env,
|
|||
|
||||
u.value >>= bits;
|
||||
/* return low 32bit and save high 32bit to temp ret */
|
||||
wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
|
||||
return (uint32) u.value;
|
||||
wasm_runtime_set_temp_ret(module_inst, (uint32)(u.value >> 32));
|
||||
return (uint32)u.value;
|
||||
}
|
||||
|
||||
static uint32
|
||||
bitshift64Shl_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 int64_part0, uint32 int64_part1,
|
||||
uint32 bits)
|
||||
bitshift64Shl_wrapper(wasm_exec_env_t exec_env, uint32 int64_part0,
|
||||
uint32 int64_part1, uint32 bits)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
union {
|
||||
|
@ -975,8 +972,8 @@ bitshift64Shl_wrapper(wasm_exec_env_t exec_env,
|
|||
|
||||
u.value <<= bits;
|
||||
/* return low 32bit and save high 32bit to temp ret */
|
||||
wasm_runtime_set_temp_ret(module_inst, (uint32) (u.value >> 32));
|
||||
return (uint32) u.value;
|
||||
wasm_runtime_set_temp_ret(module_inst, (uint32)(u.value >> 32));
|
||||
return (uint32)u.value;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -996,8 +993,8 @@ llvm_stacksave_wrapper(wasm_exec_env_t exec_env)
|
|||
}
|
||||
|
||||
static uint32
|
||||
emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env,
|
||||
void *dst, const void *src, uint32 size)
|
||||
emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env, void *dst,
|
||||
const void *src, uint32 size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
__cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 thrown_size)
|
||||
__cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 exception = module_malloc(thrown_size, NULL);
|
||||
|
@ -1050,16 +1046,12 @@ __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static void
|
||||
__cxa_begin_catch_wrapper(wasm_exec_env_t exec_env,
|
||||
void *exception_object)
|
||||
{
|
||||
}
|
||||
__cxa_begin_catch_wrapper(wasm_exec_env_t exec_env, void *exception_object)
|
||||
{}
|
||||
|
||||
static void
|
||||
__cxa_throw_wrapper(wasm_exec_env_t exec_env,
|
||||
void *thrown_exception,
|
||||
void *tinfo,
|
||||
uint32 table_elem_idx)
|
||||
__cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
|
||||
void *tinfo, uint32 table_elem_idx)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
char buf[32];
|
||||
|
@ -1074,8 +1066,8 @@ struct timespec_app {
|
|||
};
|
||||
|
||||
static uint32
|
||||
clock_gettime_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 clk_id, struct timespec_app *ts_app)
|
||||
clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
|
||||
struct timespec_app *ts_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint64 time;
|
||||
|
@ -1103,7 +1095,6 @@ static void
|
|||
print_wrapper(wasm_exec_env_t exec_env)
|
||||
{
|
||||
os_printf("in specttest.print()\n");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1137,8 +1128,10 @@ print_f64_wrapper(wasm_exec_env_t exec_env, double f64)
|
|||
}
|
||||
#endif /* WASM_ENABLE_SPEC_TEST */
|
||||
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ \
|
||||
#func_name, func_name##_wrapper, signature, NULL \
|
||||
}
|
||||
|
||||
static NativeSymbol native_symbols_libc_builtin[] = {
|
||||
REG_NATIVE_FUNC(printf, "($*)i"),
|
||||
|
@ -1281,4 +1274,3 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "sys/syscall.h"
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
#define get_module_inst(exec_env) \
|
||||
wasm_runtime_get_module_inst(exec_env)
|
||||
|
||||
|
@ -34,15 +35,15 @@
|
|||
|
||||
#define module_free(offset) \
|
||||
wasm_runtime_module_free(module_inst, offset)
|
||||
/* clang-format on */
|
||||
|
||||
extern bool
|
||||
wasm_runtime_call_indirect(wasm_exec_env_t exec_env,
|
||||
uint32 element_idx,
|
||||
wasm_runtime_call_indirect(wasm_exec_env_t exec_env, uint32 element_idx,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
static void
|
||||
invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
|
||||
int arg0, int arg1, int arg2, int arg3)
|
||||
invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
|
||||
int arg1, int arg2, int arg3)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -56,8 +57,8 @@ invoke_viiii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
|
|||
}
|
||||
|
||||
static void
|
||||
invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
|
||||
int arg0, int arg1, int arg2)
|
||||
invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
|
||||
int arg1, int arg2)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -70,8 +71,8 @@ invoke_viii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx,
|
|||
}
|
||||
|
||||
static void
|
||||
invoke_vii_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 elem_idx, int arg0, int arg1)
|
||||
invoke_vii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
|
||||
int arg1)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -83,8 +84,7 @@ invoke_vii_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static void
|
||||
invoke_vi_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 elem_idx, int arg0)
|
||||
invoke_vi_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -95,8 +95,8 @@ invoke_vi_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int
|
||||
invoke_iii_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 elem_idx, int arg0, int arg1)
|
||||
invoke_iii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0,
|
||||
int arg1)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -108,8 +108,7 @@ invoke_iii_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int
|
||||
invoke_ii_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 elem_idx, int arg0)
|
||||
invoke_ii_wrapper(wasm_exec_env_t exec_env, uint32 elem_idx, int arg0)
|
||||
{
|
||||
uint32 argv[4];
|
||||
bool ret;
|
||||
|
@ -144,8 +143,8 @@ struct stat_emcc {
|
|||
};
|
||||
|
||||
static int
|
||||
open_wrapper(wasm_exec_env_t exec_env, const char *pathname,
|
||||
int flags, int mode)
|
||||
open_wrapper(wasm_exec_env_t exec_env, const char *pathname, int flags,
|
||||
int mode)
|
||||
{
|
||||
if (pathname == NULL)
|
||||
return -1;
|
||||
|
@ -153,8 +152,7 @@ open_wrapper(wasm_exec_env_t exec_env, const char *pathname,
|
|||
}
|
||||
|
||||
static int
|
||||
__sys_read_wrapper(wasm_exec_env_t exec_env,
|
||||
int fd, void *buf, uint32 count)
|
||||
__sys_read_wrapper(wasm_exec_env_t exec_env, int fd, void *buf, uint32 count)
|
||||
{
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
@ -183,15 +181,14 @@ statbuf_native2app(const struct stat *statbuf_native,
|
|||
}
|
||||
|
||||
static int
|
||||
__sys_stat64_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *pathname,
|
||||
__sys_stat64_wrapper(wasm_exec_env_t exec_env, const char *pathname,
|
||||
struct stat_emcc *statbuf_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
int ret;
|
||||
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;
|
||||
|
||||
if (pathname == NULL)
|
||||
|
@ -204,14 +201,14 @@ __sys_stat64_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int
|
||||
__sys_fstat64_wrapper(wasm_exec_env_t exec_env,
|
||||
int fd, struct stat_emcc *statbuf_app)
|
||||
__sys_fstat64_wrapper(wasm_exec_env_t exec_env, int fd,
|
||||
struct stat_emcc *statbuf_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
int ret;
|
||||
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;
|
||||
|
||||
if (fd <= 0)
|
||||
|
@ -224,16 +221,15 @@ __sys_fstat64_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int
|
||||
mmap_wrapper(wasm_exec_env_t exec_env,
|
||||
void *addr, int length, int prot, int flags,
|
||||
int fd, int64 offset)
|
||||
mmap_wrapper(wasm_exec_env_t exec_env, void *addr, int length, int prot,
|
||||
int flags, int fd, int64 offset)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uint32 buf_offset;
|
||||
char *buf;
|
||||
int size_read;
|
||||
|
||||
buf_offset = module_malloc(length, (void**)&buf);
|
||||
buf_offset = module_malloc(length, (void **)&buf);
|
||||
if (buf_offset == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -275,16 +271,14 @@ getentropy_wrapper(wasm_exec_env_t exec_env, void *buffer, uint32 length)
|
|||
}
|
||||
|
||||
static int
|
||||
setjmp_wrapper(wasm_exec_env_t exec_env,
|
||||
void *jmp_buf)
|
||||
setjmp_wrapper(wasm_exec_env_t exec_env, void *jmp_buf)
|
||||
{
|
||||
os_printf("setjmp() called\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
longjmp_wrapper(wasm_exec_env_t exec_env,
|
||||
void *jmp_buf, int val)
|
||||
longjmp_wrapper(wasm_exec_env_t exec_env, void *jmp_buf, int val)
|
||||
{
|
||||
os_printf("longjmp() called\n");
|
||||
}
|
||||
|
@ -305,9 +299,7 @@ get_free_file_slot()
|
|||
}
|
||||
|
||||
static int
|
||||
fopen_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *pathname,
|
||||
const char *mode)
|
||||
fopen_wrapper(wasm_exec_env_t exec_env, const char *pathname, const char *mode)
|
||||
{
|
||||
FILE *file;
|
||||
int file_id;
|
||||
|
@ -327,8 +319,8 @@ fopen_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
fread_wrapper(wasm_exec_env_t exec_env,
|
||||
void *ptr, uint32 size, uint32 nmemb, int file_id)
|
||||
fread_wrapper(wasm_exec_env_t exec_env, void *ptr, uint32 size, uint32 nmemb,
|
||||
int file_id)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
|
@ -343,8 +335,7 @@ fread_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static int
|
||||
fseeko_wrapper(wasm_exec_env_t exec_env,
|
||||
int file_id, int64 offset, int whence)
|
||||
fseeko_wrapper(wasm_exec_env_t exec_env, int file_id, int64 offset, int whence)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
|
@ -359,9 +350,8 @@ fseeko_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static uint32
|
||||
emcc_fwrite_wrapper(wasm_exec_env_t exec_env,
|
||||
const void *ptr, uint32 size, uint32 nmemb,
|
||||
int file_id)
|
||||
emcc_fwrite_wrapper(wasm_exec_env_t exec_env, const void *ptr, uint32 size,
|
||||
uint32 nmemb, int file_id)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
|
@ -403,8 +393,7 @@ fclose_wrapper(wasm_exec_env_t exec_env, int file_id)
|
|||
}
|
||||
|
||||
static int
|
||||
__sys_mkdir_wrapper(wasm_exec_env_t exec_env,
|
||||
const char *pathname, int mode)
|
||||
__sys_mkdir_wrapper(wasm_exec_env_t exec_env, const char *pathname, int mode)
|
||||
{
|
||||
if (!pathname)
|
||||
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 */
|
||||
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
/* clang-format off */
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||
/* clang-format off */
|
||||
|
||||
static NativeSymbol native_symbols_libc_emcc[] = {
|
||||
REG_NATIVE_FUNC(invoke_viiii, "(iiiii)"),
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
/* clang-format off */
|
||||
#define get_module_inst(exec_env) \
|
||||
wasm_runtime_get_module_inst(exec_env)
|
||||
|
||||
|
@ -30,6 +31,7 @@
|
|||
|
||||
#define module_free(offset) \
|
||||
wasm_runtime_module_free(module_inst, offset)
|
||||
/* clang-format on */
|
||||
|
||||
#define wasi_errno_t uvwasi_errno_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
|
||||
wasi_args_sizes_get(wasm_exec_env_t exec_env,
|
||||
uint32 *argc_app, uint32 *argv_buf_size_app)
|
||||
wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
|
||||
uint32 *argv_buf_size_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
|
||||
err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -143,8 +144,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_clock_res_get(wasm_exec_env_t exec_env,
|
||||
wasi_clockid_t clock_id,
|
||||
wasi_clock_res_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
|
||||
wasi_timestamp_t *resolution)
|
||||
{
|
||||
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
|
||||
wasi_clock_time_get(wasm_exec_env_t exec_env,
|
||||
wasi_clockid_t clock_id,
|
||||
wasi_timestamp_t precision,
|
||||
wasi_timestamp_t *time)
|
||||
wasi_clock_time_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
|
||||
wasi_timestamp_t precision, wasi_timestamp_t *time)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_environ_get(wasm_exec_env_t exec_env,
|
||||
uint32 *environ_offsets, char *environ_buf)
|
||||
wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
|
||||
char *environ_buf)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_environ_sizes_get(wasm_exec_env_t exec_env,
|
||||
uint32 *environ_count_app, uint32 *environ_buf_size_app)
|
||||
wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
|
||||
uint32 *environ_buf_size_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_prestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_prestat_app_t *prestat_app)
|
||||
wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_prestat_app_t *prestat_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, char *path, uint32 path_len)
|
||||
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
|
||||
uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_pread(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_filesize_t offset, uint32 *nread_app)
|
||||
wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
|
||||
uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = uvwasi_fd_pread(uvwasi, fd, iovec_begin,
|
||||
iovs_len, offset, &nread);
|
||||
err = uvwasi_fd_pread(uvwasi, fd, iovec_begin, iovs_len, offset, &nread);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -355,8 +351,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_pwrite(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_filesize_t offset, uint32 *nwritten_app)
|
||||
{
|
||||
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;
|
||||
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin,
|
||||
iovs_len, offset, &nwritten);
|
||||
err =
|
||||
uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin, iovs_len, offset, &nwritten);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -407,9 +403,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_read(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
uint32 *nread_app)
|
||||
wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = uvwasi_fd_read(uvwasi, fd,
|
||||
iovec_begin, iovs_len, &nread);
|
||||
err = uvwasi_fd_read(uvwasi, fd, iovec_begin, iovs_len, &nread);
|
||||
if (err)
|
||||
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
|
||||
wasi_fd_seek(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filedelta_t offset, wasi_whence_t whence,
|
||||
wasi_filesize_t *newoffset)
|
||||
wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
|
||||
wasi_whence_t whence, wasi_filesize_t *newoffset)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_tell(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filesize_t *newoffset)
|
||||
wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_fdstat_t *fdstat_app)
|
||||
wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_fdstat_t *fdstat_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_fdflags_t flags)
|
||||
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_fdflags_t flags)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_rights_t fs_rights_base,
|
||||
wasi_rights_t fs_rights_inheriting)
|
||||
{
|
||||
|
@ -551,8 +542,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_fd_fdstat_set_rights(uvwasi, fd,
|
||||
fs_rights_base, fs_rights_inheriting);
|
||||
return uvwasi_fd_fdstat_set_rights(uvwasi, fd, fs_rights_base,
|
||||
fs_rights_inheriting);
|
||||
}
|
||||
|
||||
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;
|
||||
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -643,11 +634,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_advise(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_filesize_t offset,
|
||||
wasi_filesize_t len,
|
||||
wasi_advice_t advice)
|
||||
wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
|
||||
wasi_filesize_t len, wasi_advice_t advice)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_allocate(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_filesize_t offset,
|
||||
wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
|
||||
wasi_filesize_t len)
|
||||
{
|
||||
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
|
||||
wasi_path_create_directory(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const char *path, uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_path_link(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t old_fd,
|
||||
wasi_lookupflags_t old_flags,
|
||||
const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t new_fd,
|
||||
const char *new_path, uint32 new_path_len)
|
||||
wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
|
||||
wasi_lookupflags_t old_flags, const char *old_path,
|
||||
uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
|
||||
uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
|
||||
|
@ -700,20 +684,15 @@ wasi_path_link(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_path_link(uvwasi,
|
||||
old_fd, old_flags, old_path, old_path_len,
|
||||
return uvwasi_path_link(uvwasi, old_fd, old_flags, old_path, old_path_len,
|
||||
new_fd, new_path, new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_open(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t dirfd,
|
||||
wasi_lookupflags_t dirflags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_oflags_t oflags,
|
||||
wasi_rights_t fs_rights_base,
|
||||
wasi_rights_t fs_rights_inheriting,
|
||||
wasi_fdflags_t fs_flags,
|
||||
wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
|
||||
wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
|
||||
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)
|
||||
{
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = uvwasi_path_open(uvwasi,
|
||||
dirfd, dirflags,
|
||||
path, path_len,
|
||||
oflags,
|
||||
fs_rights_base,
|
||||
fs_rights_inheriting,
|
||||
fs_flags,
|
||||
&fd);
|
||||
err = uvwasi_path_open(uvwasi, dirfd, dirflags, path, path_len, oflags,
|
||||
fs_rights_base, fs_rights_inheriting, fs_flags, &fd);
|
||||
|
||||
*fd_app = fd;
|
||||
return err;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_readdir(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
void *buf, uint32 buf_len,
|
||||
wasi_dircookie_t cookie,
|
||||
uint32 *bufused_app)
|
||||
wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
|
||||
uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = uvwasi_fd_readdir(uvwasi, fd,
|
||||
buf, buf_len, cookie, &bufused);
|
||||
err = uvwasi_fd_readdir(uvwasi, fd, buf, buf_len, cookie, &bufused);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -768,10 +737,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_readlink(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
const char *path, uint32 path_len,
|
||||
char *buf, uint32 buf_len,
|
||||
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
|
||||
uint32 path_len, char *buf, uint32 buf_len,
|
||||
uint32 *bufused_app)
|
||||
{
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = uvwasi_path_readlink(uvwasi, fd,
|
||||
path, path_len,
|
||||
buf, buf_len, &bufused);
|
||||
err = uvwasi_path_readlink(uvwasi, fd, path, path_len, buf, buf_len,
|
||||
&bufused);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -796,9 +762,9 @@ wasi_path_readlink(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_rename(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len)
|
||||
wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
|
||||
const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
|
||||
const char *new_path, uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
|
||||
|
@ -806,14 +772,13 @@ wasi_path_rename(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_path_rename(uvwasi,
|
||||
old_fd, old_path, old_path_len,
|
||||
new_fd, new_path, new_path_len);
|
||||
return uvwasi_path_rename(uvwasi, old_fd, old_path, old_path_len, new_fd,
|
||||
new_path, new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_filestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filestat_t *filestat)
|
||||
wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_filestat_t *filestat)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_timestamp_t st_atim,
|
||||
wasi_timestamp_t st_mtim,
|
||||
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
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);
|
||||
|
@ -840,13 +803,11 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_fd_filestat_set_times(uvwasi, fd,
|
||||
st_atim, st_mtim, fstflags);
|
||||
return uvwasi_fd_filestat_set_times(uvwasi, fd, st_atim, st_mtim, fstflags);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_filesize_t st_size)
|
||||
{
|
||||
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
|
||||
wasi_path_filestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_filestat_t *filestat)
|
||||
wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags, const char *path,
|
||||
uint32 path_len, wasi_filestat_t *filestat)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_path_filestat_get(uvwasi, fd,
|
||||
flags, path, path_len, filestat);
|
||||
return uvwasi_path_filestat_get(uvwasi, fd, flags, path, path_len,
|
||||
filestat);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_filestat_set_times(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_timestamp_t st_atim,
|
||||
wasi_timestamp_t st_mtim,
|
||||
wasi_fstflags_t fstflags)
|
||||
wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags, const char *path,
|
||||
uint32 path_len, 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);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_path_filestat_set_times(uvwasi, fd,
|
||||
flags, path, path_len,
|
||||
return uvwasi_path_filestat_set_times(uvwasi, fd, flags, path, path_len,
|
||||
st_atim, st_mtim, fstflags);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_symlink(wasm_exec_env_t exec_env,
|
||||
const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t fd, const char *new_path, uint32 new_path_len)
|
||||
wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
|
||||
uint32 old_path_len, wasi_fd_t fd, const char *new_path,
|
||||
uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
|
||||
|
@ -909,14 +864,13 @@ wasi_path_symlink(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return uvwasi_path_symlink(uvwasi,
|
||||
old_path, old_path_len, fd,
|
||||
new_path, new_path_len);
|
||||
return uvwasi_path_symlink(uvwasi, old_path, old_path_len, fd, new_path,
|
||||
new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_unlink_file(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
|
||||
uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_path_remove_directory(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const char *path, uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_poll_oneoff(wasm_exec_env_t exec_env,
|
||||
const wasi_subscription_t *in, wasi_event_t *out,
|
||||
uint32 nsubscriptions, uint32 *nevents_app)
|
||||
wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
||||
wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
|
||||
|
@ -953,13 +906,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
|
|||
if (!uvwasi)
|
||||
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(nevents_app, sizeof(uint32)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = uvwasi_poll_oneoff(uvwasi, in, out,
|
||||
nsubscriptions, &nevents);
|
||||
err = uvwasi_poll_oneoff(uvwasi, in, out, nsubscriptions, &nevents);
|
||||
if (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
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock,
|
||||
iovec_app_t *ri_data, uint32 ri_data_len,
|
||||
wasi_riflags_t ri_flags,
|
||||
uint32 *ro_datalen_app,
|
||||
wasi_roflags_t *ro_flags)
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
|
||||
uint32 ri_data_len, 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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = uvwasi_sock_recv(uvwasi, sock,
|
||||
iovec_begin, ri_data_len,
|
||||
ri_flags, &ro_datalen,
|
||||
ro_flags);
|
||||
err = uvwasi_sock_recv(uvwasi, sock, iovec_begin, ri_data_len, ri_flags,
|
||||
&ro_datalen, ro_flags);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
*(uint32*)ro_datalen_app = (uint32)ro_datalen;
|
||||
*(uint32 *)ro_datalen_app = (uint32)ro_datalen;
|
||||
|
||||
/* success */
|
||||
err = 0;
|
||||
|
@ -1055,11 +1002,9 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_send(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock,
|
||||
wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
|
||||
const iovec_app_t *si_data, uint32 si_data_len,
|
||||
wasi_siflags_t si_flags,
|
||||
uint32 *so_datalen_app)
|
||||
wasi_siflags_t si_flags, uint32 *so_datalen_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
if (!validate_native_addr(so_datalen_app, sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = uvwasi_sock_send(uvwasi, sock,
|
||||
ciovec_begin, si_data_len,
|
||||
si_flags, &so_datalen);
|
||||
err = uvwasi_sock_send(uvwasi, sock, ciovec_begin, si_data_len, si_flags,
|
||||
&so_datalen);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -1110,8 +1054,7 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_shutdown(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock, wasi_sdflags_t how)
|
||||
wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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);
|
||||
}
|
||||
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
/* clang-format off */
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ #func_name, wasi_##func_name, signature, NULL }
|
||||
/* clang-format on */
|
||||
|
||||
static NativeSymbol native_symbols_libc_wasi[] = {
|
||||
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;
|
||||
return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
void
|
||||
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
|
||||
|
||||
/* clang-format off */
|
||||
#define 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) \
|
||||
wasm_runtime_module_free(module_inst, offset)
|
||||
/* clang-format on */
|
||||
|
||||
typedef struct wasi_prestat_app {
|
||||
wasi_preopentype_t pr_type;
|
||||
|
@ -52,14 +54,13 @@ typedef struct WASIContext {
|
|||
char **argv_list;
|
||||
char *env_buf;
|
||||
char **env_list;
|
||||
} *wasi_ctx_t;
|
||||
} * wasi_ctx_t;
|
||||
|
||||
wasi_ctx_t
|
||||
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
|
||||
|
||||
static inline struct fd_table *
|
||||
wasi_ctx_get_curfds(wasm_module_inst_t module_inst,
|
||||
wasi_ctx_t wasi_ctx)
|
||||
wasi_ctx_get_curfds(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
||||
{
|
||||
if (!wasi_ctx)
|
||||
return NULL;
|
||||
|
@ -67,8 +68,7 @@ wasi_ctx_get_curfds(wasm_module_inst_t module_inst,
|
|||
}
|
||||
|
||||
static inline struct argv_environ_values *
|
||||
wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst,
|
||||
wasi_ctx_t wasi_ctx)
|
||||
wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
||||
{
|
||||
if (!wasi_ctx)
|
||||
return NULL;
|
||||
|
@ -76,8 +76,7 @@ wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst,
|
|||
}
|
||||
|
||||
static inline struct fd_prestats *
|
||||
wasi_ctx_get_prestats(wasm_module_inst_t module_inst,
|
||||
wasi_ctx_t wasi_ctx)
|
||||
wasi_ctx_get_prestats(wasm_module_inst_t module_inst, wasi_ctx_t wasi_ctx)
|
||||
{
|
||||
if (!wasi_ctx)
|
||||
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);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
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;
|
||||
char **argv;
|
||||
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))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
total_size = sizeof(char*) * ((uint64)argc + 1);
|
||||
total_size = sizeof(char *) * ((uint64)argc + 1);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(argv = wasm_runtime_malloc((uint32)total_size)))
|
||||
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
|
||||
wasi_args_sizes_get(wasm_exec_env_t exec_env,
|
||||
uint32 *argc_app, uint32 *argv_buf_size_app)
|
||||
wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
|
||||
uint32 *argv_buf_size_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
|
||||
err = wasmtime_ssp_args_sizes_get(argv_environ,
|
||||
&argc, &argv_buf_size);
|
||||
err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -173,7 +171,7 @@ wasi_clock_res_get(wasm_exec_env_t exec_env,
|
|||
|
||||
static wasi_errno_t
|
||||
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 *time /* uint64 *time */)
|
||||
{
|
||||
|
@ -186,13 +184,13 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_environ_get(wasm_exec_env_t exec_env,
|
||||
uint32 *environ_offsets, char *environ_buf)
|
||||
wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
|
||||
char *environ_buf)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
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;
|
||||
uint64 total_size;
|
||||
char **environs;
|
||||
|
@ -201,8 +199,8 @@ wasi_environ_get(wasm_exec_env_t exec_env,
|
|||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_environ_sizes_get(argv_environ,
|
||||
&environ_count, &environ_buf_size);
|
||||
err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count,
|
||||
&environ_buf_size);
|
||||
if (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))
|
||||
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
|
||||
|| !(environs = wasm_runtime_malloc((uint32)total_size)))
|
||||
|
@ -234,13 +232,13 @@ wasi_environ_get(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_environ_sizes_get(wasm_exec_env_t exec_env,
|
||||
uint32 *environ_count_app, uint32 *environ_buf_size_app)
|
||||
wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
|
||||
uint32 *environ_buf_size_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
|
||||
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;
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_environ_sizes_get(argv_environ,
|
||||
&environ_count, &environ_buf_size);
|
||||
err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count,
|
||||
&environ_buf_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -263,8 +261,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_prestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_prestat_app_t *prestat_app)
|
||||
wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_prestat_app_t *prestat_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, char *path, uint32 path_len)
|
||||
wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
|
||||
uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_fd_prestat_dir_name(prestats,
|
||||
fd, path, path_len);
|
||||
return wasmtime_ssp_fd_prestat_dir_name(prestats, fd, path, path_len);
|
||||
}
|
||||
|
||||
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
|
||||
wasi_fd_pread(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_filesize_t offset, uint32 *nread_app)
|
||||
wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
|
||||
uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin,
|
||||
iovs_len, offset, &nread);
|
||||
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset,
|
||||
&nread);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -384,8 +380,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_pwrite(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
wasi_filesize_t offset, uint32 *nwritten_app)
|
||||
{
|
||||
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;
|
||||
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin,
|
||||
iovs_len, offset, &nwritten);
|
||||
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset,
|
||||
&nwritten);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -438,9 +434,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_read(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const iovec_app_t *iovec_app, uint32 iovs_len,
|
||||
uint32 *nread_app)
|
||||
wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_fd_read(curfds, fd,
|
||||
iovec_begin, iovs_len, &nread);
|
||||
err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread);
|
||||
if (err)
|
||||
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
|
||||
wasi_fd_seek(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filedelta_t offset, wasi_whence_t whence,
|
||||
wasi_filesize_t *newoffset)
|
||||
wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
|
||||
wasi_whence_t whence, wasi_filesize_t *newoffset)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_tell(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filesize_t *newoffset)
|
||||
wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_fdstat_t *fdstat_app)
|
||||
wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_fdstat_t *fdstat_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_fdflags_t flags)
|
||||
wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_fdflags_t flags)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_rights_t fs_rights_base,
|
||||
wasi_rights_t fs_rights_inheriting)
|
||||
{
|
||||
|
@ -591,8 +582,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
|
|||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd,
|
||||
fs_rights_base, fs_rights_inheriting);
|
||||
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base,
|
||||
fs_rights_inheriting);
|
||||
}
|
||||
|
||||
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;
|
||||
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_fd_write(curfds, fd,
|
||||
ciovec_begin, iovs_len, &nwritten);
|
||||
err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
|
@ -663,11 +653,8 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_advise(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_filesize_t offset,
|
||||
wasi_filesize_t len,
|
||||
wasi_advice_t advice)
|
||||
wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
|
||||
wasi_filesize_t len, wasi_advice_t advice)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_allocate(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_filesize_t offset,
|
||||
wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
|
||||
wasi_filesize_t len)
|
||||
{
|
||||
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
|
||||
wasi_path_create_directory(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const char *path, uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_create_directory(curfds, fd,
|
||||
path, path_len);
|
||||
return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_link(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t old_fd,
|
||||
wasi_lookupflags_t old_flags,
|
||||
const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t new_fd,
|
||||
const char *new_path, uint32 new_path_len)
|
||||
wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
|
||||
wasi_lookupflags_t old_flags, const char *old_path,
|
||||
uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
|
||||
uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_link(curfds, prestats,
|
||||
old_fd, old_flags, old_path, old_path_len,
|
||||
new_fd, new_path, new_path_len);
|
||||
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path,
|
||||
old_path_len, new_fd, new_path, new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_open(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t dirfd,
|
||||
wasi_lookupflags_t dirflags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_oflags_t oflags,
|
||||
wasi_rights_t fs_rights_base,
|
||||
wasi_rights_t fs_rights_inheriting,
|
||||
wasi_fdflags_t fs_flags,
|
||||
wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
|
||||
wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
|
||||
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)
|
||||
{
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_path_open(curfds,
|
||||
dirfd, dirflags,
|
||||
path, path_len,
|
||||
oflags,
|
||||
fs_rights_base,
|
||||
fs_rights_inheriting,
|
||||
fs_flags,
|
||||
&fd);
|
||||
err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len,
|
||||
oflags, fs_rights_base, fs_rights_inheriting,
|
||||
fs_flags, &fd);
|
||||
|
||||
*fd_app = fd;
|
||||
return err;
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_readdir(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
void *buf, uint32 buf_len,
|
||||
wasi_dircookie_t cookie,
|
||||
uint32 *bufused_app)
|
||||
wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
|
||||
uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_fd_readdir(curfds, fd,
|
||||
buf, buf_len, cookie, &bufused);
|
||||
err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -796,10 +764,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_readlink(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
const char *path, uint32 path_len,
|
||||
char *buf, uint32 buf_len,
|
||||
wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
|
||||
uint32 path_len, char *buf, uint32 buf_len,
|
||||
uint32 *bufused_app)
|
||||
{
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_path_readlink(curfds, fd,
|
||||
path, path_len,
|
||||
buf, buf_len, &bufused);
|
||||
err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len,
|
||||
&bufused);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -825,9 +790,9 @@ wasi_path_readlink(wasm_exec_env_t exec_env,
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_rename(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t old_fd, const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t new_fd, const char *new_path, uint32 new_path_len)
|
||||
wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
|
||||
const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
|
||||
const char *new_path, uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_rename(curfds,
|
||||
old_fd, old_path, old_path_len,
|
||||
return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len,
|
||||
new_fd, new_path, new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_filestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, wasi_filestat_t *filestat)
|
||||
wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_filestat_t *filestat)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_timestamp_t st_atim,
|
||||
wasi_timestamp_t st_mtim,
|
||||
wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
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);
|
||||
|
@ -872,13 +834,12 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
|
|||
if (!wasi_ctx)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_fd_filestat_set_times(curfds, fd,
|
||||
st_atim, st_mtim, fstflags);
|
||||
return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim,
|
||||
fstflags);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_filesize_t st_size)
|
||||
{
|
||||
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
|
||||
wasi_path_filestat_get(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_filestat_t *filestat)
|
||||
wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags, const char *path,
|
||||
uint32 path_len, wasi_filestat_t *filestat)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_filestat_get(curfds, fd,
|
||||
flags, path, path_len, filestat);
|
||||
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len,
|
||||
filestat);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_filestat_set_times(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags,
|
||||
const char *path, uint32 path_len,
|
||||
wasi_timestamp_t st_atim,
|
||||
wasi_timestamp_t st_mtim,
|
||||
wasi_fstflags_t fstflags)
|
||||
wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
wasi_lookupflags_t flags, const char *path,
|
||||
uint32 path_len, 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);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_filestat_set_times(curfds, fd,
|
||||
flags, path, path_len,
|
||||
st_atim, st_mtim, fstflags);
|
||||
return wasmtime_ssp_path_filestat_set_times(
|
||||
curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_symlink(wasm_exec_env_t exec_env,
|
||||
const char *old_path, uint32 old_path_len,
|
||||
wasi_fd_t fd, const char *new_path, uint32 new_path_len)
|
||||
wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
|
||||
uint32 old_path_len, wasi_fd_t fd, const char *new_path,
|
||||
uint32 new_path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
return wasmtime_ssp_path_symlink(curfds, prestats,
|
||||
old_path, old_path_len, fd,
|
||||
new_path, new_path_len);
|
||||
return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len,
|
||||
fd, new_path, new_path_len);
|
||||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_path_unlink_file(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
|
||||
uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_path_remove_directory(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t fd, const char *path, uint32 path_len)
|
||||
wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
|
||||
const char *path, uint32 path_len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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
|
||||
wasi_poll_oneoff(wasm_exec_env_t exec_env,
|
||||
const wasi_subscription_t *in, wasi_event_t *out,
|
||||
uint32 nsubscriptions, uint32 *nevents_app)
|
||||
wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
|
||||
wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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)
|
||||
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(nevents_app, sizeof(uint32)))
|
||||
return (wasi_errno_t)-1;
|
||||
|
||||
err = wasmtime_ssp_poll_oneoff(curfds, in, out,
|
||||
nsubscriptions, &nevents);
|
||||
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
|
||||
if (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
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock,
|
||||
iovec_app_t *ri_data, uint32 ri_data_len,
|
||||
wasi_riflags_t ri_flags,
|
||||
uint32 *ro_datalen_app,
|
||||
wasi_roflags_t *ro_flags)
|
||||
wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
|
||||
uint32 ri_data_len, 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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_sock_recv(curfds, sock,
|
||||
iovec_begin, ri_data_len,
|
||||
ri_flags, &ro_datalen,
|
||||
ro_flags);
|
||||
err = wasmtime_ssp_sock_recv(curfds, sock, iovec_begin, ri_data_len,
|
||||
ri_flags, &ro_datalen, ro_flags);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
*(uint32*)ro_datalen_app = (uint32)ro_datalen;
|
||||
*(uint32 *)ro_datalen_app = (uint32)ro_datalen;
|
||||
|
||||
/* success */
|
||||
err = 0;
|
||||
|
@ -1095,11 +1042,9 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_send(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock,
|
||||
wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
|
||||
const iovec_app_t *si_data, uint32 si_data_len,
|
||||
wasi_siflags_t si_flags,
|
||||
uint32 *so_datalen_app)
|
||||
wasi_siflags_t si_flags, uint32 *so_datalen_app)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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;
|
||||
if (!validate_native_addr(so_datalen_app, sizeof(uint32))
|
||||
|| 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
err = wasmtime_ssp_sock_send(curfds, sock,
|
||||
ciovec_begin, si_data_len,
|
||||
err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len,
|
||||
si_flags, &so_datalen);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
@ -1152,8 +1096,7 @@ fail:
|
|||
}
|
||||
|
||||
static wasi_errno_t
|
||||
wasi_sock_shutdown(wasm_exec_env_t exec_env,
|
||||
wasi_fd_t sock, wasi_sdflags_t how)
|
||||
wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
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();
|
||||
}
|
||||
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
/* clang-format off */
|
||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||
{ #func_name, wasi_##func_name, signature, NULL }
|
||||
/* clang-format on */
|
||||
|
||||
static NativeSymbol native_symbols_libc_wasi[] = {
|
||||
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;
|
||||
return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
* See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
* Part of the Wasmtime Project, under the Apache License v2.0 with
|
||||
* 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
|
||||
* some implementation details such as the curfds arguments that we pass
|
||||
|
@ -13,6 +15,8 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef _Static_assert
|
||||
#define _Static_assert static_assert
|
||||
|
@ -28,7 +32,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
_Static_assert(_Alignof(int8_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");
|
||||
|
@ -891,5 +894,6 @@ __wasi_errno_t wasmtime_ssp_sched_yield(void)
|
|||
|
||||
#undef WASMTIME_SSP_SYSCALL_NAME
|
||||
|
||||
#endif
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* end of WASMTIME_SSP_H */
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -32,13 +34,13 @@
|
|||
#define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__))
|
||||
|
||||
#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 UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__))
|
||||
|
||||
#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_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__))
|
||||
|
||||
|
@ -50,8 +52,10 @@ struct LOCKABLE mutex {
|
|||
pthread_mutex_t object;
|
||||
};
|
||||
|
||||
/* clang-format off */
|
||||
#define MUTEX_INITIALIZER \
|
||||
{ PTHREAD_MUTEX_INITIALIZER }
|
||||
{ PTHREAD_MUTEX_INITIALIZER }
|
||||
/* clang-format on */
|
||||
|
||||
static inline bool
|
||||
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 {
|
||||
pthread_cond_t object;
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
clockid_t clock;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline bool
|
||||
cond_init_monotonic(struct cond *cond) {
|
||||
cond_init_monotonic(struct cond *cond)
|
||||
{
|
||||
bool ret = false;
|
||||
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
|
||||
pthread_condattr_t attr;
|
||||
|
@ -147,8 +152,8 @@ fail:
|
|||
ret = true;
|
||||
#endif
|
||||
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
cond->clock = CLOCK_MONOTONIC;
|
||||
#endif
|
||||
return ret;
|
||||
|
@ -159,28 +164,29 @@ cond_init_realtime(struct cond *cond)
|
|||
{
|
||||
if (pthread_cond_init(&cond->object, NULL) != 0)
|
||||
return false;
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
cond->clock = CLOCK_REALTIME;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cond_destroy(struct cond *cond) {
|
||||
cond_destroy(struct cond *cond)
|
||||
{
|
||||
pthread_cond_destroy(&cond->object);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cond_signal(struct cond *cond) {
|
||||
cond_signal(struct cond *cond)
|
||||
{
|
||||
pthread_cond_signal(&cond->object);
|
||||
}
|
||||
|
||||
#if !CONFIG_HAS_CLOCK_NANOSLEEP
|
||||
static inline bool
|
||||
cond_timedwait(struct cond *cond, struct mutex *lock,
|
||||
uint64_t timeout, bool abstime)
|
||||
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
|
||||
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||
{
|
||||
int ret;
|
||||
struct timespec ts = {
|
||||
|
@ -220,8 +226,8 @@ cond_timedwait(struct cond *cond, struct mutex *lock,
|
|||
else {
|
||||
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
/* Implementation supports relative timeouts. */
|
||||
ret = pthread_cond_timedwait_relative_np(&cond->object,
|
||||
&lock->object, &ts);
|
||||
ret = pthread_cond_timedwait_relative_np(&cond->object, &lock->object,
|
||||
&ts);
|
||||
bh_assert((ret == 0 || ret == ETIMEDOUT)
|
||||
&& "pthread_cond_timedwait_relative_np() failed");
|
||||
return ret == ETIMEDOUT;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -12,29 +14,29 @@
|
|||
#ifndef COMMON_LIMITS_H
|
||||
#define COMMON_LIMITS_H
|
||||
|
||||
#define NUMERIC_MIN(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MIN, signed char \
|
||||
: SCHAR_MIN, unsigned char : 0, short \
|
||||
: SHRT_MIN, unsigned short : 0, int \
|
||||
: INT_MIN, unsigned int : 0, long \
|
||||
: LONG_MIN, unsigned long : 0, long long \
|
||||
: LLONG_MIN, unsigned long long : 0, default \
|
||||
: (void)0)
|
||||
#define NUMERIC_MIN(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MIN, signed char \
|
||||
: SCHAR_MIN, unsigned char : 0, short \
|
||||
: SHRT_MIN, unsigned short : 0, int \
|
||||
: INT_MIN, unsigned int : 0, long \
|
||||
: LONG_MIN, unsigned long : 0, long long \
|
||||
: LLONG_MIN, unsigned long long : 0, default \
|
||||
: (void)0)
|
||||
|
||||
#define NUMERIC_MAX(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MAX, signed char \
|
||||
: SCHAR_MAX, unsigned char \
|
||||
: UCHAR_MAX, short \
|
||||
: SHRT_MAX, unsigned short \
|
||||
: USHRT_MAX, int \
|
||||
: INT_MAX, unsigned int \
|
||||
: UINT_MAX, long \
|
||||
: LONG_MAX, unsigned long \
|
||||
: ULONG_MAX, long long \
|
||||
: LLONG_MAX, unsigned long long \
|
||||
: ULLONG_MAX, default \
|
||||
: (void)0)
|
||||
#define NUMERIC_MAX(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MAX, signed char \
|
||||
: SCHAR_MAX, unsigned char \
|
||||
: UCHAR_MAX, short \
|
||||
: SHRT_MAX, unsigned short \
|
||||
: USHRT_MAX, int \
|
||||
: INT_MAX, unsigned int \
|
||||
: UINT_MAX, long \
|
||||
: LONG_MAX, unsigned long \
|
||||
: ULONG_MAX, long long \
|
||||
: LLONG_MAX, unsigned long long \
|
||||
: ULLONG_MAX, default \
|
||||
: (void)0)
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -20,41 +22,48 @@ struct fd_prestat;
|
|||
struct syscalls;
|
||||
|
||||
struct fd_table {
|
||||
struct rwlock lock;
|
||||
struct fd_entry *entries;
|
||||
size_t size;
|
||||
size_t used;
|
||||
struct rwlock lock;
|
||||
struct fd_entry *entries;
|
||||
size_t size;
|
||||
size_t used;
|
||||
};
|
||||
|
||||
struct fd_prestats {
|
||||
struct rwlock lock;
|
||||
struct fd_prestat *prestats;
|
||||
size_t size;
|
||||
size_t used;
|
||||
struct rwlock lock;
|
||||
struct fd_prestat *prestats;
|
||||
size_t size;
|
||||
size_t used;
|
||||
};
|
||||
|
||||
struct argv_environ_values {
|
||||
const char *argv_buf;
|
||||
size_t argv_buf_size;
|
||||
char **argv_list;
|
||||
size_t argc;
|
||||
char *environ_buf;
|
||||
size_t environ_buf_size;
|
||||
char **environ_list;
|
||||
size_t environ_count;
|
||||
const char *argv_buf;
|
||||
size_t argv_buf_size;
|
||||
char **argv_list;
|
||||
size_t argc;
|
||||
char *environ_buf;
|
||||
size_t environ_buf_size;
|
||||
char **environ_list;
|
||||
size_t environ_count;
|
||||
};
|
||||
|
||||
bool fd_table_init(struct fd_table *);
|
||||
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
|
||||
bool fd_prestats_init(struct fd_prestats *);
|
||||
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
|
||||
bool argv_environ_init(struct argv_environ_values *argv_environ,
|
||||
char *argv_buf, size_t argv_buf_size,
|
||||
char **argv_list, size_t argc,
|
||||
char *environ_buf, size_t environ_buf_size,
|
||||
char **environ_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);
|
||||
bool
|
||||
fd_table_init(struct fd_table *);
|
||||
bool
|
||||
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
|
||||
bool
|
||||
fd_prestats_init(struct fd_prestats *);
|
||||
bool
|
||||
fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
|
||||
bool
|
||||
argv_environ_init(struct argv_environ_values *argv_environ, char *argv_buf,
|
||||
size_t argv_buf_size, char **argv_list, size_t argc,
|
||||
char *environ_buf, size_t environ_buf_size,
|
||||
char **environ_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
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -15,76 +17,82 @@
|
|||
// LIST: Double-linked list.
|
||||
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *l_first; \
|
||||
}
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
struct name { \
|
||||
struct type *l_first; \
|
||||
}
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *l_next; \
|
||||
struct type **l_prev; \
|
||||
}
|
||||
/* clang-format off */
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
/* clang-format on */
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *l_next; \
|
||||
struct type **l_prev; \
|
||||
}
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
|
||||
#define LIST_INIT(head) \
|
||||
do { \
|
||||
(head)->l_first = NULL; \
|
||||
} while (0)
|
||||
#define LIST_INSERT_HEAD(head, element, field) \
|
||||
do { \
|
||||
(element)->field.l_next = (head)->l_first; \
|
||||
if ((head)->l_first != NULL) \
|
||||
(head)->l_first->field.l_prev = &(element)->field.l_next; \
|
||||
(head)->l_first = (element); \
|
||||
(element)->field.l_prev = &(head)->l_first; \
|
||||
} while (0)
|
||||
#define LIST_REMOVE(element, field) \
|
||||
do { \
|
||||
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)
|
||||
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
|
||||
|
||||
#define LIST_INIT(head) \
|
||||
do { \
|
||||
(head)->l_first = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, element, field) \
|
||||
do { \
|
||||
(element)->field.l_next = (head)->l_first; \
|
||||
if ((head)->l_first != NULL) \
|
||||
(head)->l_first->field.l_prev = &(element)->field.l_next; \
|
||||
(head)->l_first = (element); \
|
||||
(element)->field.l_prev = &(head)->l_first; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_REMOVE(element, field) \
|
||||
do { \
|
||||
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.
|
||||
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *t_first; \
|
||||
struct type **t_last; \
|
||||
}
|
||||
struct name { \
|
||||
struct type *t_first; \
|
||||
struct type **t_last; \
|
||||
}
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *t_next; \
|
||||
struct type **t_prev; \
|
||||
}
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *t_next; \
|
||||
struct type **t_prev; \
|
||||
}
|
||||
|
||||
#define TAILQ_EMPTY(head) ((head)->t_first == NULL)
|
||||
#define TAILQ_FIRST(head) ((head)->t_first)
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
|
||||
#define TAILQ_INIT(head) \
|
||||
do { \
|
||||
(head)->t_first = NULL; \
|
||||
(head)->t_last = &(head)->t_first; \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do { \
|
||||
(elm)->field.t_next = NULL; \
|
||||
(elm)->field.t_prev = (head)->t_last; \
|
||||
*(head)->t_last = (elm); \
|
||||
(head)->t_last = &(elm)->field.t_next; \
|
||||
} while (0)
|
||||
#define TAILQ_REMOVE(head, element, field) \
|
||||
do { \
|
||||
if ((element)->field.t_next != NULL) \
|
||||
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \
|
||||
else \
|
||||
(head)->t_last = (element)->field.t_prev; \
|
||||
*(element)->field.t_prev = (element)->field.t_next; \
|
||||
} while (0)
|
||||
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
|
||||
#define TAILQ_INIT(head) \
|
||||
do { \
|
||||
(head)->t_first = NULL; \
|
||||
(head)->t_last = &(head)->t_first; \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do { \
|
||||
(elm)->field.t_next = NULL; \
|
||||
(elm)->field.t_prev = (head)->t_last; \
|
||||
*(head)->t_last = (elm); \
|
||||
(head)->t_last = &(elm)->field.t_next; \
|
||||
} while (0)
|
||||
#define TAILQ_REMOVE(head, element, field) \
|
||||
do { \
|
||||
if ((element)->field.t_next != NULL) \
|
||||
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \
|
||||
else \
|
||||
(head)->t_last = (element)->field.t_prev; \
|
||||
*(element)->field.t_prev = (element)->field.t_next; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -15,8 +17,10 @@
|
|||
|
||||
#if CONFIG_HAS_ARC4RANDOM_BUF
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
arc4random_buf(buf, len);
|
||||
void
|
||||
random_buf(void *buf, size_t len)
|
||||
{
|
||||
arc4random_buf(buf, len);
|
||||
}
|
||||
|
||||
#elif CONFIG_HAS_GETRANDOM
|
||||
|
@ -25,42 +29,48 @@ void random_buf(void *buf, size_t len) {
|
|||
#include <sys/random.h>
|
||||
#endif
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
for (;;) {
|
||||
ssize_t x = getrandom(buf, len, 0);
|
||||
if (x < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
os_printf("getrandom failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if ((size_t)x == len)
|
||||
return;
|
||||
buf = (void *)((unsigned char *)buf + x);
|
||||
len -= (size_t)x;
|
||||
}
|
||||
void
|
||||
random_buf(void *buf, size_t len)
|
||||
{
|
||||
for (;;) {
|
||||
ssize_t x = getrandom(buf, len, 0);
|
||||
if (x < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
os_printf("getrandom failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if ((size_t)x == len)
|
||||
return;
|
||||
buf = (void *)((unsigned char *)buf + x);
|
||||
len -= (size_t)x;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int urandom;
|
||||
|
||||
static void open_urandom(void) {
|
||||
urandom = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom < 0) {
|
||||
os_printf("Failed to open /dev/urandom\n");
|
||||
abort();
|
||||
}
|
||||
static void
|
||||
open_urandom(void)
|
||||
{
|
||||
urandom = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom < 0) {
|
||||
os_printf("Failed to open /dev/urandom\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&open_once, open_urandom);
|
||||
void
|
||||
random_buf(void *buf, size_t len)
|
||||
{
|
||||
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&open_once, open_urandom);
|
||||
|
||||
if ((size_t)read(urandom, buf, len) != len) {
|
||||
os_printf("Short read on /dev/urandom\n");
|
||||
abort();
|
||||
}
|
||||
if ((size_t)read(urandom, buf, len) != len) {
|
||||
os_printf("Short read on /dev/urandom\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
// this range has length k * upper, we can safely obtain a number
|
||||
// without any modulo bias.
|
||||
uintmax_t random_uniform(uintmax_t upper) {
|
||||
// Compute 2^k % upper
|
||||
// == (2^k - upper) % upper
|
||||
// == -upper % upper.
|
||||
uintmax_t lower = -upper % upper;
|
||||
for (;;) {
|
||||
uintmax_t value;
|
||||
random_buf(&value, sizeof(value));
|
||||
if (value >= lower)
|
||||
return value % upper;
|
||||
}
|
||||
uintmax_t
|
||||
random_uniform(uintmax_t upper)
|
||||
{
|
||||
// Compute 2^k % upper
|
||||
// == (2^k - upper) % upper
|
||||
// == -upper % upper.
|
||||
uintmax_t lower = -upper % upper;
|
||||
for (;;) {
|
||||
uintmax_t value;
|
||||
random_buf(&value, sizeof(value));
|
||||
if (value >= lower)
|
||||
return value % upper;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -12,7 +14,8 @@
|
|||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
void random_buf(void *, size_t);
|
||||
void
|
||||
random_buf(void *, size_t);
|
||||
uintmax_t random_uniform(uintmax_t);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -46,8 +48,8 @@ refcount_acquire(struct refcount *r) PRODUCES(*r)
|
|||
static inline bool
|
||||
refcount_release(struct refcount *r) CONSUMES(*r)
|
||||
{
|
||||
int old = (int)atomic_fetch_sub_explicit(&r->count, 1,
|
||||
memory_order_release);
|
||||
int old =
|
||||
(int)atomic_fetch_sub_explicit(&r->count, 1, memory_order_release);
|
||||
bh_assert(old != 0 && "Reference count becoming negative");
|
||||
return old == 1;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -12,6 +14,8 @@
|
|||
#ifndef RIGHTS_H
|
||||
#define RIGHTS_H
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define RIGHTS_ALL \
|
||||
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
|
||||
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
|
@ -80,4 +84,6 @@
|
|||
__WASI_RIGHT_POLL_FD_READWRITE)
|
||||
#define RIGHTS_TTY_INHERITING 0
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -12,6 +14,7 @@
|
|||
#ifndef SIGNALS_H
|
||||
#define SIGNALS_H
|
||||
|
||||
void signals_init(void);
|
||||
void
|
||||
signals_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -14,7 +16,8 @@
|
|||
|
||||
#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
|
||||
#else
|
||||
#define CONFIG_HAS_ARC4RANDOM_BUF 0
|
||||
|
@ -22,10 +25,9 @@
|
|||
|
||||
// On Linux, prefer to use getrandom, though it isn't available in
|
||||
// GLIBC before 2.25.
|
||||
#if defined(__linux__) && \
|
||||
(!defined(__GLIBC__) || \
|
||||
__GLIBC__ > 2 || \
|
||||
(__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
#if defined(__linux__) \
|
||||
&& (!defined(__GLIBC__) || __GLIBC__ > 2 \
|
||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
#define CONFIG_HAS_GETRANDOM 1
|
||||
#else
|
||||
#define CONFIG_HAS_GETRANDOM 0
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -27,7 +29,8 @@ bh_strndup(const char *s, size_t n)
|
|||
}
|
||||
|
||||
char *
|
||||
str_nullterminate(const char *s, size_t len) {
|
||||
str_nullterminate(const char *s, size_t len)
|
||||
{
|
||||
/* Copy string */
|
||||
char *ret = bh_strndup(s, len);
|
||||
|
||||
|
@ -40,5 +43,5 @@ str_nullterminate(const char *s, size_t len) {
|
|||
errno = EILSEQ;
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license information.
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license
|
||||
// information.
|
||||
//
|
||||
// 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
|
||||
|
@ -14,6 +16,7 @@
|
|||
|
||||
#include "ssp_config.h"
|
||||
|
||||
char *str_nullterminate(const char *, size_t);
|
||||
char *
|
||||
str_nullterminate(const char *, size_t);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
typedef struct {
|
||||
bh_list_link l;
|
||||
|
||||
void (*destroy_cb)(WASMCluster *);
|
||||
} DestroyCallBackNode;
|
||||
|
||||
|
@ -133,8 +132,7 @@ wasm_cluster_create(WASMExecEnv *exec_env)
|
|||
}
|
||||
|
||||
/* Prepare the aux stack top and size for every thread */
|
||||
if (!wasm_exec_env_get_aux_stack(exec_env,
|
||||
&aux_stack_start,
|
||||
if (!wasm_exec_env_get_aux_stack(exec_env, &aux_stack_start,
|
||||
&aux_stack_size)) {
|
||||
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);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(cluster->stack_tops =
|
||||
wasm_runtime_malloc((uint32)total_size))) {
|
||||
wasm_runtime_malloc((uint32)total_size))) {
|
||||
goto fail;
|
||||
}
|
||||
memset(cluster->stack_tops, 0, (uint32)total_size);
|
||||
|
||||
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;
|
||||
}
|
||||
memset(cluster->stack_segment_occupied, 0,
|
||||
|
@ -215,8 +213,8 @@ destroy_cluster_visitor(void *node, void *user_data)
|
|||
void
|
||||
wasm_cluster_destroy(WASMCluster *cluster)
|
||||
{
|
||||
traverse_list(destroy_callback_list,
|
||||
destroy_cluster_visitor, (void *)cluster);
|
||||
traverse_list(destroy_callback_list, destroy_cluster_visitor,
|
||||
(void *)cluster);
|
||||
|
||||
/* Remove the cluster from the cluster list */
|
||||
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
|
||||
module instance have a corresponding exec_env */
|
||||
module instance have a corresponding exec_env */
|
||||
WASMExecEnv *
|
||||
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst)
|
||||
{
|
||||
|
@ -338,21 +336,19 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!(new_module_inst =
|
||||
wasm_runtime_instantiate_internal(module, true, 8192,
|
||||
0, NULL, 0))) {
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, true, 8192, 0, NULL, 0))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (module_inst) {
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst,
|
||||
wasm_runtime_get_custom_data(module_inst));
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
}
|
||||
|
||||
new_exec_env = wasm_exec_env_create_internal(
|
||||
new_module_inst, exec_env->wasm_stack_size);
|
||||
new_exec_env = wasm_exec_env_create_internal(new_module_inst,
|
||||
exec_env->wasm_stack_size);
|
||||
if (!new_exec_env)
|
||||
goto fail1;
|
||||
|
||||
|
@ -400,7 +396,7 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
|
|||
}
|
||||
|
||||
/* start routine of thread manager */
|
||||
static void*
|
||||
static void *
|
||||
thread_manager_start_routine(void *arg)
|
||||
{
|
||||
void *ret;
|
||||
|
@ -432,8 +428,7 @@ thread_manager_start_routine(void *arg)
|
|||
int32
|
||||
wasm_cluster_create_thread(WASMExecEnv *exec_env,
|
||||
wasm_module_inst_t module_inst,
|
||||
void* (*thread_routine)(void *),
|
||||
void *arg)
|
||||
void *(*thread_routine)(void *), void *arg)
|
||||
{
|
||||
WASMCluster *cluster;
|
||||
WASMExecEnv *new_exec_env;
|
||||
|
@ -443,8 +438,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
|
|||
cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
bh_assert(cluster);
|
||||
|
||||
new_exec_env = wasm_exec_env_create_internal(
|
||||
module_inst, exec_env->wasm_stack_size);
|
||||
new_exec_env =
|
||||
wasm_exec_env_create_internal(module_inst, exec_env->wasm_stack_size);
|
||||
if (!new_exec_env)
|
||||
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_arg = arg;
|
||||
|
||||
if (0 != os_thread_create(&tid, thread_manager_start_routine,
|
||||
(void *)new_exec_env,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT)) {
|
||||
if (0
|
||||
!= os_thread_create(&tid, thread_manager_start_routine,
|
||||
(void *)new_exec_env,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT)) {
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
|
@ -520,9 +516,10 @@ wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status)
|
|||
}
|
||||
|
||||
inline static bool
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -532,7 +529,7 @@ wasm_cluster_clear_thread_signal(WASMExecEnv *exec_env)
|
|||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
exec_env->current_status->running_status = STATUS_RUNNING;
|
||||
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;
|
||||
os_cond_signal(&exec_env->wait_cond);
|
||||
|
@ -654,12 +653,12 @@ wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
|||
{
|
||||
/* Set the termination flag */
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
|
||||
wasm_cluster_thread_exited(exec_env);
|
||||
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
|
||||
wasm_cluster_thread_exited(exec_env);
|
||||
#else
|
||||
exec_env->suspend_flags.flags |= 0x01;
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -678,16 +677,15 @@ terminate_thread_visitor(void *node, void *user_data)
|
|||
void
|
||||
wasm_cluster_terminate_all(WASMCluster *cluster)
|
||||
{
|
||||
traverse_list(&cluster->exec_env_list,
|
||||
terminate_thread_visitor, NULL);
|
||||
traverse_list(&cluster->exec_env_list, terminate_thread_visitor, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
|
||||
WASMExecEnv *exec_env)
|
||||
{
|
||||
traverse_list(&cluster->exec_env_list,
|
||||
terminate_thread_visitor, (void *)exec_env);
|
||||
traverse_list(&cluster->exec_env_list, terminate_thread_visitor,
|
||||
(void *)exec_env);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -726,16 +724,15 @@ suspend_thread_visitor(void *node, void *user_data)
|
|||
void
|
||||
wasm_cluster_suspend_all(WASMCluster *cluster)
|
||||
{
|
||||
traverse_list(&cluster->exec_env_list,
|
||||
suspend_thread_visitor, NULL);
|
||||
traverse_list(&cluster->exec_env_list, suspend_thread_visitor, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
|
||||
WASMExecEnv *exec_env)
|
||||
{
|
||||
traverse_list(&cluster->exec_env_list,
|
||||
suspend_thread_visitor, (void *)exec_env);
|
||||
traverse_list(&cluster->exec_env_list, suspend_thread_visitor,
|
||||
(void *)exec_env);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -765,8 +762,7 @@ set_exception_visitor(void *node, void *user_data)
|
|||
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
|
||||
WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
|
||||
WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env);
|
||||
WASMModuleInstanceCommon *curr_module_inst =
|
||||
get_module_inst(curr_exec_env);
|
||||
WASMModuleInstanceCommon *curr_module_inst = get_module_inst(curr_exec_env);
|
||||
const char *exception = wasm_runtime_get_exception(module_inst);
|
||||
/* skip "Exception: " */
|
||||
exception += 11;
|
||||
|
@ -806,7 +802,6 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
|
|||
cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
bh_assert(cluster);
|
||||
|
||||
traverse_list(&cluster->exec_env_list,
|
||||
set_custom_data_visitor,
|
||||
traverse_list(&cluster->exec_env_list, set_custom_data_visitor,
|
||||
custom_data);
|
||||
}
|
||||
|
|
|
@ -16,30 +16,28 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#define WAMR_SIG_TRAP (5)
|
||||
#define WAMR_SIG_STOP (19)
|
||||
#define WAMR_SIG_TERM (15)
|
||||
#define WAMR_SIG_SINGSTEP (0x1ff)
|
||||
#define WAMR_SIG_TRAP (5)
|
||||
#define WAMR_SIG_STOP (19)
|
||||
#define WAMR_SIG_TERM (15)
|
||||
#define WAMR_SIG_SINGSTEP (0x1ff)
|
||||
|
||||
#define STATUS_RUNNING (0)
|
||||
#define STATUS_STOP (1)
|
||||
#define STATUS_EXIT (2)
|
||||
#define STATUS_STEP (3)
|
||||
#define STATUS_STOP (1)
|
||||
#define STATUS_EXIT (2)
|
||||
#define STATUS_STEP (3)
|
||||
|
||||
#define IS_WAMR_TERM_SIG(signo) \
|
||||
((signo) == WAMR_SIG_TERM)
|
||||
#define IS_WAMR_TERM_SIG(signo) ((signo) == WAMR_SIG_TERM)
|
||||
|
||||
#define IS_WAMR_STOP_SIG(signo) \
|
||||
((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
|
||||
|
||||
typedef struct WASMCurrentEnvStatus
|
||||
{
|
||||
uint64 signal_flag:32;
|
||||
uint64 step_count:16;
|
||||
uint64 running_status:16;
|
||||
typedef struct WASMCurrentEnvStatus {
|
||||
uint64 signal_flag : 32;
|
||||
uint64 step_count : 16;
|
||||
uint64 running_status : 16;
|
||||
korp_mutex wait_lock;
|
||||
korp_cond wait_cond;
|
||||
}WASMCurrentEnvStatus;
|
||||
} WASMCurrentEnvStatus;
|
||||
|
||||
WASMCurrentEnvStatus *
|
||||
wasm_cluster_create_exenv_status();
|
||||
|
@ -57,7 +55,7 @@ void
|
|||
wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 * status);
|
||||
wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 *status);
|
||||
|
||||
void
|
||||
wasm_cluster_thread_exited(WASMExecEnv *exec_env);
|
||||
|
@ -72,8 +70,7 @@ void
|
|||
wasm_cluster_thread_step(WASMExecEnv *exec_env);
|
||||
|
||||
#endif
|
||||
typedef struct WASMCluster
|
||||
{
|
||||
typedef struct WASMCluster {
|
||||
struct WASMCluster *next;
|
||||
|
||||
korp_mutex lock;
|
||||
|
@ -89,7 +86,8 @@ typedef struct WASMCluster
|
|||
bool *stack_segment_occupied;
|
||||
} WASMCluster;
|
||||
|
||||
void wasm_cluster_set_max_thread_num(uint32 num);
|
||||
void
|
||||
wasm_cluster_set_max_thread_num(uint32 num);
|
||||
|
||||
bool
|
||||
thread_manager_init();
|
||||
|
@ -106,14 +104,13 @@ void
|
|||
wasm_cluster_destroy(WASMCluster *cluster);
|
||||
|
||||
/* Get the cluster of the current exec_env */
|
||||
WASMCluster*
|
||||
WASMCluster *
|
||||
wasm_exec_env_get_cluster(WASMExecEnv *exec_env);
|
||||
|
||||
int32
|
||||
wasm_cluster_create_thread(WASMExecEnv *exec_env,
|
||||
wasm_module_inst_t module_inst,
|
||||
void* (*thread_routine)(void *),
|
||||
void *arg);
|
||||
void *(*thread_routine)(void *), void *arg);
|
||||
|
||||
int32
|
||||
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val);
|
||||
|
|
Loading…
Reference in New Issue
Block a user