Enable AoT and wamr-sdk, and change arguments of call wasm API (#157)
* Implement memory profiler, optimize memory usage, modify code indent * Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default * Add a new extension library: connection * Fix bug of reading magic number and version in big endian platform * Re-org platform APIs: move most platform APIs from iwasm to shared-lib * Enhance wasm loader to fix some security issues * Fix issue about illegal load of EXC_RETURN into PC on stm32 board * Updates that let a restricted version of the interpreter run in SGX * Enable native/app address validation and conversion for wasm app * Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused * Refine binary size and fix several minor issues Optimize interpreter LOAD/STORE opcodes to decrease the binary size Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper Add macros of global heap size, stack size, heap size for Zephyr main.c Clear compile warning of wasm_application.c * Add more strict security checks for libc wrapper API's * Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files * Enhance security of libc strcpy/sprintf wrapper function * Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions * Remove get_module_inst() and fix issue of call native * Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate * Refine interpreter call native process, refine memory boudary check * Fix issues of invokeNative function of arm/mips/general version * Add a switch to build simple sample without gui support * Add BUILD_TARGET setting in makefile to replace cpu compiler flags in source code * Re-org shared lib header files, remove unused info; fix compile issues of vxworks * Add build target general * Remove unused files * Update license header * test push * Restore file * Sync up with internal/feature * Sync up with internal/feature * Rename build_wamr_app to build_wasm_app * Fix small issues of README * Enhance malformed wasm file checking Fix issue of print hex int and implement utf8 string check Fix wasi file read/write right issue Fix minor issue of build wasm app doc * Sync up with internal/feature * Sync up with internal/feature: fix interpreter arm issue, fix read leb issue * Sync up with internal/feature * Fix bug of config.h and rename wasi config.h to ssp_config.h * Sync up with internal/feature * Import wamr aot * update document * update document * Update document, disable WASI in 32bit * update document * remove files * update document * Update document * update document * update document * update samples * Sync up with internal repo
This commit is contained in:
2511
core/iwasm/aot/aot_loader.c
Normal file
2511
core/iwasm/aot/aot_loader.c
Normal file
File diff suppressed because it is too large
Load Diff
858
core/iwasm/aot/aot_runtime.c
Normal file
858
core/iwasm/aot/aot_runtime.c
Normal file
@ -0,0 +1,858 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "aot_runtime.h"
|
||||
#include "bh_memory.h"
|
||||
#include "bh_log.h"
|
||||
#include "mem_alloc.h"
|
||||
|
||||
static void
|
||||
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||
{
|
||||
if (error_buf != NULL)
|
||||
snprintf(error_buf, error_buf_size, "%s", string);
|
||||
}
|
||||
|
||||
static bool
|
||||
global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i;
|
||||
InitializerExpression *init_expr;
|
||||
uint8 *p = (uint8*)module_inst->global_data.ptr;
|
||||
AOTImportGlobal *import_global = module->import_globals;;
|
||||
AOTGlobal *global = module->globals;
|
||||
|
||||
/* Initialize import global data */
|
||||
for (i = 0; i < module->import_global_count; i++, import_global++) {
|
||||
bh_assert(import_global->data_offset ==
|
||||
p - (uint8*)module_inst->global_data.ptr);
|
||||
memcpy(p, &import_global->global_data_linked, import_global->size);
|
||||
p += import_global->size;
|
||||
}
|
||||
|
||||
/* Initialize defined global data */
|
||||
for (i = 0; i < module->global_count; i++, global++) {
|
||||
bh_assert(global->data_offset ==
|
||||
p - (uint8*)module_inst->global_data.ptr);
|
||||
init_expr = &global->init_expr;
|
||||
switch (init_expr->init_expr_type) {
|
||||
case INIT_EXPR_TYPE_GET_GLOBAL:
|
||||
bh_assert(init_expr->u.global_index < module->import_global_count);
|
||||
memcpy(p,
|
||||
&module->import_globals[init_expr->u.global_index].global_data_linked,
|
||||
global->size);
|
||||
break;
|
||||
default:
|
||||
/* TODO: check whether global type and init_expr type are matching */
|
||||
memcpy(p, &init_expr->u, global->size);
|
||||
break;
|
||||
}
|
||||
p += global->size;
|
||||
}
|
||||
|
||||
bh_assert(module_inst->global_data_size == p - (uint8*)module_inst->global_data.ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i, global_index, global_data_offset, base_offset, length;
|
||||
AOTTableInitData *table_seg;
|
||||
|
||||
if (module->table_init_data_count > 0) {
|
||||
for (i = 0; i < module->table_init_data_count; i++) {
|
||||
table_seg = module->table_init_data_list[i];
|
||||
bh_assert(table_seg->offset.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST
|
||||
|| table_seg->offset.init_expr_type ==
|
||||
INIT_EXPR_TYPE_GET_GLOBAL);
|
||||
|
||||
/* Resolve table data base offset */
|
||||
if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
|
||||
global_index = table_seg->offset.u.global_index;
|
||||
bh_assert(global_index <
|
||||
module->import_global_count + module->global_count);
|
||||
/* TODO: && globals[table_seg->offset.u.global_index].type ==
|
||||
VALUE_TYPE_I32*/
|
||||
if (global_index < module->import_global_count)
|
||||
global_data_offset =
|
||||
module->import_globals[global_index].data_offset;
|
||||
else
|
||||
global_data_offset =
|
||||
module->globals[global_index - module->import_global_count]
|
||||
.data_offset;
|
||||
|
||||
base_offset = *(uint32*)
|
||||
((uint8*)module_inst->global_data.ptr + global_data_offset);
|
||||
}
|
||||
else
|
||||
base_offset = (uint32)table_seg->offset.u.i32;
|
||||
|
||||
/* Copy table data */
|
||||
length = table_seg->func_index_count;
|
||||
if (base_offset < module_inst->table_size) {
|
||||
memcpy((uint32*)module_inst->table_data.ptr + base_offset,
|
||||
table_seg->func_indexes, length * sizeof(uint32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i, global_index, global_data_offset, base_offset, length;
|
||||
AOTMemInitData *data_seg;
|
||||
uint64 total_size = (uint64)NumBytesPerPage * module->mem_init_page_count;
|
||||
|
||||
/* Allocate memory */
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module_inst->memory_data.ptr = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module_inst->memory_data.ptr, 0, (uint32)total_size);
|
||||
|
||||
/* Init memory info */
|
||||
module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr
|
||||
+ total_size;
|
||||
module_inst->memory_data_size = (uint32)total_size;
|
||||
module_inst->mem_cur_page_count = module->mem_init_page_count;
|
||||
module_inst->mem_max_page_count = module->mem_max_page_count;
|
||||
|
||||
if (module->mem_init_page_count > 0) {
|
||||
for (i = 0; i < module->mem_init_data_count; i++) {
|
||||
data_seg = module->mem_init_data_list[i];
|
||||
bh_assert(data_seg->offset.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST
|
||||
|| data_seg->offset.init_expr_type ==
|
||||
INIT_EXPR_TYPE_GET_GLOBAL);
|
||||
|
||||
/* Resolve memory data base offset */
|
||||
if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
|
||||
global_index = data_seg->offset.u.global_index;
|
||||
bh_assert(global_index <
|
||||
module->import_global_count + module->global_count);
|
||||
/* TODO: && globals[data_seg->offset.u.global_index].type ==
|
||||
VALUE_TYPE_I32*/
|
||||
if (global_index < module->import_global_count)
|
||||
global_data_offset =
|
||||
module->import_globals[global_index].data_offset;
|
||||
else
|
||||
global_data_offset =
|
||||
module->globals[global_index - module->import_global_count]
|
||||
.data_offset;
|
||||
|
||||
base_offset = *(uint32*)
|
||||
((uint8*)module_inst->global_data.ptr + global_data_offset);
|
||||
}
|
||||
else
|
||||
base_offset = (uint32)data_seg->offset.u.i32;
|
||||
|
||||
length = data_seg->byte_count;
|
||||
|
||||
/* Check memory data */
|
||||
if (length > 0
|
||||
&& (base_offset >= module_inst->memory_data_size
|
||||
|| base_offset + length > module_inst->memory_data_size)) {
|
||||
wasm_free(module_inst->memory_data.ptr);
|
||||
module_inst->memory_data.ptr = NULL;
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: data segment out of range.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Copy memory data */
|
||||
memcpy((uint8*)module_inst->memory_data.ptr + base_offset,
|
||||
data_seg->bytes, length);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i;
|
||||
void **func_ptrs;
|
||||
uint64 total_size =
|
||||
((uint64)module->import_func_count + module->func_count) * sizeof(void*);
|
||||
|
||||
/* Allocate memory */
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module_inst->func_ptrs.ptr = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module_inst->func_ptrs.ptr, 0, (uint32)total_size);
|
||||
|
||||
/* Set import function pointers */
|
||||
func_ptrs = (void**)module_inst->func_ptrs.ptr;
|
||||
for (i = 0; i < module->import_func_count; i++, func_ptrs++)
|
||||
*func_ptrs = (void*)module->import_funcs[i].func_ptr_linked;
|
||||
|
||||
/* Set defined function pointers */
|
||||
memcpy(func_ptrs, module->func_ptrs, module->func_count * sizeof(void*));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 *func_type_index;
|
||||
uint64 total_size =
|
||||
((uint64)module->import_func_count + module->func_count) * sizeof(uint32);
|
||||
|
||||
/* Allocate memory */
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module_inst->func_type_indexes.ptr = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module_inst->func_type_indexes.ptr, 0, (uint32)total_size);
|
||||
|
||||
/* Set import function type indexes */
|
||||
func_type_index = (uint32*)module_inst->func_type_indexes.ptr;
|
||||
for (i = 0; i < module->import_func_count; i++, func_type_index++)
|
||||
*func_type_index = module->import_funcs[i].func_type_index;
|
||||
|
||||
memcpy(func_type_index, module->func_type_indexes,
|
||||
module->func_count * sizeof(uint32));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
execute_post_inst_function(AOTModuleInstance *module_inst)
|
||||
{
|
||||
AOTFunctionInstance *post_inst_func =
|
||||
aot_lookup_function(module_inst, "__post_instantiate", "()");
|
||||
|
||||
if (!post_inst_func)
|
||||
/* Not found */
|
||||
return true;
|
||||
|
||||
return aot_create_exec_env_and_call_function(module_inst, post_inst_func, 0, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
execute_start_function(AOTModuleInstance *module_inst)
|
||||
{
|
||||
AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
|
||||
WASMExecEnv *exec_env;
|
||||
typedef void (*F)(WASMExecEnv*);
|
||||
union { F f; void *v; } u;
|
||||
|
||||
if (!module->start_function)
|
||||
return true;
|
||||
|
||||
if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
|
||||
module_inst->default_wasm_stack_size))) {
|
||||
aot_set_exception(module_inst, "allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
u.v = module->start_function;
|
||||
u.f(exec_env);
|
||||
|
||||
wasm_exec_env_destroy(exec_env);
|
||||
return !aot_get_exception(module_inst);
|
||||
}
|
||||
|
||||
AOTModuleInstance*
|
||||
aot_instantiate(AOTModule *module,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
AOTModuleInstance *module_inst;
|
||||
uint32 module_inst_struct_size =
|
||||
offsetof(AOTModuleInstance, global_table_heap_data.bytes);
|
||||
uint64 table_data_size = (uint64)module->table_size * sizeof(uint32);
|
||||
uint64 total_size = (uint64)module_inst_struct_size
|
||||
+ module->global_data_size
|
||||
+ table_data_size + heap_size;
|
||||
void *heap_handle;
|
||||
uint8 *p;
|
||||
|
||||
/* Check heap size */
|
||||
heap_size = align_uint(heap_size, 8);
|
||||
if (heap_size == 0)
|
||||
heap_size = APP_HEAP_SIZE_DEFAULT;
|
||||
if (heap_size < APP_HEAP_SIZE_MIN)
|
||||
heap_size = APP_HEAP_SIZE_MIN;
|
||||
if (heap_size > APP_HEAP_SIZE_MAX)
|
||||
heap_size = APP_HEAP_SIZE_MAX;
|
||||
|
||||
/* Allocate module instance, global data, table data and heap data */
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module_inst = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(module_inst, 0, total_size);
|
||||
module_inst->module_type = Wasm_Module_AoT;
|
||||
module_inst->aot_module.ptr = module;
|
||||
|
||||
/* Initialize global info */
|
||||
p = (uint8*)module_inst + module_inst_struct_size;
|
||||
module_inst->global_data.ptr = p;
|
||||
module_inst->global_data_size = module->global_data_size;
|
||||
if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Initialize table info */
|
||||
p += module->global_data_size;
|
||||
module_inst->table_data.ptr = p;
|
||||
module_inst->table_size = module->table_size;
|
||||
/* Set all elements to -1 to mark them as uninitialized elements */
|
||||
memset(module_inst->table_data.ptr, -1, (uint32)table_data_size);
|
||||
if (!table_instantiate(module_inst, module, error_buf, error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Initialize heap info */
|
||||
p += (uint32)table_data_size;
|
||||
module_inst->heap_data.ptr = p;
|
||||
p += heap_size;
|
||||
module_inst->heap_data_end.ptr = p;
|
||||
module_inst->heap_data_size = heap_size;
|
||||
#if WASM_ENABLE_MEMORY_GROW != 0
|
||||
module_inst->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET;
|
||||
#else
|
||||
module_inst->heap_base_offset = module_inst->memory_data_size;
|
||||
#endif
|
||||
if (!(heap_handle = mem_allocator_create(module_inst->heap_data.ptr,
|
||||
heap_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"AOT module instantiate failed: init app heap failed.");
|
||||
goto fail;
|
||||
}
|
||||
module_inst->heap_handle.ptr = heap_handle;
|
||||
|
||||
/* Initialize memory space */
|
||||
if (!memory_instantiate(module_inst, module, error_buf, error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Initialize function pointers */
|
||||
if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Initialize function type indexes */
|
||||
if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
|
||||
goto fail;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (!wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
|
||||
module->wasi_args.dir_list,
|
||||
module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list,
|
||||
module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env,
|
||||
module->wasi_args.env_count,
|
||||
module->wasi_args.argv,
|
||||
module->wasi_args.argc,
|
||||
error_buf, error_buf_size))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
/* Initialize the thread related data */
|
||||
if (stack_size == 0)
|
||||
stack_size = DEFAULT_WASM_STACK_SIZE;
|
||||
module_inst->default_wasm_stack_size = stack_size;
|
||||
|
||||
/* Execute __post_instantiate function and start function*/
|
||||
if (!execute_post_inst_function(module_inst)
|
||||
|| !execute_start_function(module_inst)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
module_inst->cur_exception);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return module_inst;
|
||||
|
||||
fail:
|
||||
aot_deinstantiate(module_inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aot_deinstantiate(AOTModuleInstance *module_inst)
|
||||
{
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
/* Destroy wasi resource before freeing app heap, since some fields of
|
||||
wasi contex are allocated from app heap, and if app heap is freed,
|
||||
these fields will be set to NULL, we cannot free their internal data
|
||||
which may allocated from global heap. */
|
||||
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->memory_data.ptr)
|
||||
wasm_free(module_inst->memory_data.ptr);
|
||||
|
||||
if (module_inst->heap_handle.ptr)
|
||||
mem_allocator_destroy(module_inst->heap_handle.ptr);
|
||||
|
||||
if (module_inst->func_ptrs.ptr)
|
||||
wasm_free(module_inst->func_ptrs.ptr);
|
||||
|
||||
if (module_inst->func_type_indexes.ptr)
|
||||
wasm_free(module_inst->func_type_indexes.ptr);
|
||||
|
||||
wasm_free(module_inst);
|
||||
}
|
||||
|
||||
static bool
|
||||
check_type(uint8 type, const char *p)
|
||||
{
|
||||
const char *str = "i32";
|
||||
|
||||
if (strlen(p) < 3)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case VALUE_TYPE_I32:
|
||||
str = "i32";
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
str = "i64";
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
str = "f32";
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
str = "f64";
|
||||
break;
|
||||
}
|
||||
if (strncmp(p, str, 3))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_function_type(const WASMType *type,
|
||||
const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
const char *p = signature;
|
||||
|
||||
if (!p || *p++ != '(')
|
||||
return false;
|
||||
|
||||
for (i = 0; i < type->param_count; i++) {
|
||||
if (!check_type(type->types[i], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p++ != ')')
|
||||
return false;
|
||||
|
||||
if (type->result_count) {
|
||||
if (!check_type(type->types[type->param_count], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AOTFunctionInstance*
|
||||
aot_lookup_function(const AOTModuleInstance *module_inst,
|
||||
const char *name, const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
|
||||
|
||||
for (i = 0; i < module->export_func_count; i++) {
|
||||
if (!strcmp(module->export_funcs[i].func_name, name)
|
||||
&& check_function_type(module->export_funcs[i].func_type,
|
||||
signature))
|
||||
return &module->export_funcs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define PUT_I64_TO_ADDR(addr, value) do { \
|
||||
union { int64 val; uint32 parts[2]; } u; \
|
||||
u.val = (value); \
|
||||
(addr)[0] = u.parts[0]; \
|
||||
(addr)[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
|
||||
#define PUT_F64_TO_ADDR(addr, value) do { \
|
||||
union { float64 val; uint32 parts[2]; } u; \
|
||||
u.val = (value); \
|
||||
(addr)[0] = u.parts[0]; \
|
||||
(addr)[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
|
||||
bool
|
||||
aot_call_function(WASMExecEnv *exec_env,
|
||||
AOTFunctionInstance *function,
|
||||
unsigned argc, uint32 argv[])
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
|
||||
AOTFuncType *func_type = function->func_type;
|
||||
bool ret = wasm_runtime_invoke_native(function->func_ptr, func_type,
|
||||
exec_env, argv, argc, argv);
|
||||
return ret && !aot_get_exception(module_inst) ? true : false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
|
||||
AOTFunctionInstance *func,
|
||||
unsigned argc, uint32 argv[])
|
||||
{
|
||||
WASMExecEnv *exec_env;
|
||||
bool ret;
|
||||
|
||||
if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
|
||||
module_inst->default_wasm_stack_size))) {
|
||||
aot_set_exception(module_inst, "allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = aot_call_function(exec_env, func, argc, argv);
|
||||
wasm_exec_env_destroy(exec_env);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
aot_set_exception(AOTModuleInstance *module_inst,
|
||||
const char *exception)
|
||||
{
|
||||
if (exception)
|
||||
snprintf(module_inst->cur_exception,
|
||||
sizeof(module_inst->cur_exception),
|
||||
"Exception: %s", exception);
|
||||
else
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
aot_set_exception_with_id(AOTModuleInstance *module_inst,
|
||||
uint32 id)
|
||||
{
|
||||
switch (id) {
|
||||
case EXCE_UNREACHABLE:
|
||||
aot_set_exception(module_inst, "unreachable");
|
||||
break;
|
||||
case EXCE_OUT_OF_MEMORY:
|
||||
aot_set_exception(module_inst, "allocate memory failed");
|
||||
break;
|
||||
case EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS:
|
||||
aot_set_exception(module_inst, "out of bounds memory access");
|
||||
break;
|
||||
case EXCE_INTEGER_OVERFLOW:
|
||||
aot_set_exception(module_inst, "integer overflow");
|
||||
break;
|
||||
case EXCE_INTEGER_DIVIDE_BY_ZERO:
|
||||
aot_set_exception(module_inst, "integer divide by zero");
|
||||
break;
|
||||
case EXCE_INVALID_CONVERSION_TO_INTEGER:
|
||||
aot_set_exception(module_inst, "invalid conversion to integer");
|
||||
break;
|
||||
case EXCE_INVALID_FUNCTION_TYPE_INDEX:
|
||||
aot_set_exception(module_inst, "indirect call type mismatch");
|
||||
break;
|
||||
case EXCE_INVALID_FUNCTION_INDEX:
|
||||
aot_set_exception(module_inst, "invalid function index");
|
||||
break;
|
||||
case EXCE_UNDEFINED_ELEMENT:
|
||||
aot_set_exception(module_inst, "undefined element");
|
||||
break;
|
||||
case EXCE_UNINITIALIZED_ELEMENT:
|
||||
aot_set_exception(module_inst, "uninitialized element");
|
||||
break;
|
||||
case EXCE_CALL_UNLINKED_IMPORT_FUNC:
|
||||
aot_set_exception(module_inst, "fail to call unlinked import function");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
aot_get_exception(AOTModuleInstance *module_inst)
|
||||
{
|
||||
if (module_inst->cur_exception[0] == '\0')
|
||||
return NULL;
|
||||
else
|
||||
return module_inst->cur_exception;
|
||||
}
|
||||
|
||||
void
|
||||
aot_clear_exception(AOTModuleInstance *module_inst)
|
||||
{
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
|
||||
int32
|
||||
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size)
|
||||
{
|
||||
uint8 *addr =
|
||||
mem_allocator_malloc(module_inst->heap_handle.ptr, size);
|
||||
|
||||
if (!addr) {
|
||||
aot_set_exception(module_inst, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
return (int32)(module_inst->heap_base_offset
|
||||
+ (addr - (uint8*)module_inst->heap_data.ptr));
|
||||
}
|
||||
|
||||
void
|
||||
aot_module_free(AOTModuleInstance *module_inst, int32 ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
uint8 *addr = (uint8*)module_inst->heap_data.ptr
|
||||
+ (ptr - module_inst->heap_base_offset);
|
||||
if ((uint8*)module_inst->heap_data.ptr < addr
|
||||
&& addr < (uint8*)module_inst->heap_data_end.ptr)
|
||||
mem_allocator_free(module_inst->heap_handle.ptr, addr);
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
aot_module_dup_data(AOTModuleInstance *module_inst,
|
||||
const char *src, uint32 size)
|
||||
{
|
||||
int32 buffer_offset = aot_module_malloc(module_inst, size);
|
||||
|
||||
if (buffer_offset != 0) {
|
||||
char *buffer;
|
||||
buffer = aot_addr_app_to_native(module_inst, buffer_offset);
|
||||
memcpy(buffer, src, size);
|
||||
}
|
||||
return buffer_offset;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_validate_app_addr(AOTModuleInstance *module_inst,
|
||||
int32 app_offset, uint32 size)
|
||||
{
|
||||
uint8 *addr;
|
||||
|
||||
/* integer overflow check */
|
||||
if(app_offset + (int32)size < app_offset) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (0 <= app_offset
|
||||
&& app_offset < (int32)module_inst->memory_data_size) {
|
||||
addr = (uint8*)module_inst->memory_data.ptr + app_offset;
|
||||
if (!((uint8*)module_inst->memory_data.ptr <= addr
|
||||
&& addr + size <= (uint8*)module_inst->memory_data_end.ptr))
|
||||
goto fail;
|
||||
return true;
|
||||
}
|
||||
/* Currently heap_size is no more than 1G, and heap_base_offset is 1G,
|
||||
heap_base_offset + heap_data_size will not be larger than INT32_MAX */
|
||||
else if (module_inst->heap_base_offset < app_offset
|
||||
&& app_offset < module_inst->heap_base_offset
|
||||
+ (int32)module_inst->heap_data_size) {
|
||||
addr = (uint8*)module_inst->heap_data.ptr
|
||||
+ (app_offset - module_inst->heap_base_offset);
|
||||
if (!((uint8*)module_inst->heap_data.ptr <= addr
|
||||
&& addr + size <= (uint8*)module_inst->heap_data_end.ptr))
|
||||
goto fail;
|
||||
return true;
|
||||
}
|
||||
|
||||
fail:
|
||||
aot_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_validate_native_addr(AOTModuleInstance *module_inst,
|
||||
void *native_ptr, uint32 size)
|
||||
{
|
||||
uint8 *addr = native_ptr;
|
||||
|
||||
/* integer overflow check */
|
||||
if (addr + size < addr) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (((uint8*)module_inst->memory_data.ptr <= addr
|
||||
&& addr + size <= (uint8*)module_inst->memory_data_end.ptr)
|
||||
|| ((uint8*)module_inst->heap_data.ptr <= addr
|
||||
&& addr + size <= (uint8*)module_inst->heap_data_end.ptr)
|
||||
)
|
||||
return true;
|
||||
|
||||
fail:
|
||||
aot_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
void *
|
||||
aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset)
|
||||
{
|
||||
if (0 <= app_offset && app_offset < module_inst->heap_base_offset)
|
||||
return (uint8*)module_inst->memory_data.ptr + app_offset;
|
||||
|
||||
if (module_inst->heap_base_offset < app_offset
|
||||
&& app_offset < module_inst->heap_base_offset
|
||||
+ (int32)module_inst->heap_data_size)
|
||||
return (uint8*)module_inst->heap_data.ptr
|
||||
+ (app_offset - module_inst->heap_base_offset);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32
|
||||
aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr)
|
||||
{
|
||||
if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr)
|
||||
return (int32)((uint8*)native_ptr - (uint8*)module_inst->memory_data.ptr);
|
||||
|
||||
if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr)
|
||||
return (int32)(module_inst->heap_base_offset
|
||||
+ ((uint8*)native_ptr - (uint8*)module_inst->heap_data.ptr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_get_app_addr_range(AOTModuleInstance *module_inst,
|
||||
int32 app_offset,
|
||||
int32 *p_app_start_offset,
|
||||
int32 *p_app_end_offset)
|
||||
{
|
||||
int32 app_start_offset, app_end_offset;
|
||||
|
||||
if (0 <= app_offset && app_offset < (int32)module_inst->memory_data_size) {
|
||||
app_start_offset = 0;
|
||||
app_end_offset = (int32)module_inst->memory_data_size;
|
||||
}
|
||||
else if (module_inst->heap_base_offset < app_offset
|
||||
&& app_offset < module_inst->heap_base_offset
|
||||
+ (int32)module_inst->heap_data_size) {
|
||||
app_start_offset = module_inst->heap_base_offset;
|
||||
app_end_offset = module_inst->heap_base_offset
|
||||
+ (int32)module_inst->heap_data_size;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if (p_app_start_offset)
|
||||
*p_app_start_offset = app_start_offset;
|
||||
if (p_app_end_offset)
|
||||
*p_app_end_offset = app_end_offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_get_native_addr_range(AOTModuleInstance *module_inst,
|
||||
uint8 *native_ptr,
|
||||
uint8 **p_native_start_addr,
|
||||
uint8 **p_native_end_addr)
|
||||
{
|
||||
uint8 *native_start_addr, *native_end_addr;
|
||||
|
||||
if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) {
|
||||
native_start_addr = (uint8*)module_inst->memory_data.ptr;
|
||||
native_end_addr = (uint8*)module_inst->memory_data_end.ptr;
|
||||
}
|
||||
else if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr) {
|
||||
native_start_addr = (uint8*)module_inst->heap_data.ptr;
|
||||
native_end_addr = (uint8*)module_inst->heap_data_end.ptr;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if (p_native_start_addr)
|
||||
*p_native_start_addr = native_start_addr;
|
||||
if (p_native_end_addr)
|
||||
*p_native_end_addr = native_end_addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
||||
{
|
||||
uint8 *mem_data_old = module_inst->memory_data.ptr, *mem_data_new;
|
||||
uint32 cur_page_count = module_inst->mem_cur_page_count;
|
||||
uint32 max_page_count = module_inst->mem_max_page_count;
|
||||
uint32 total_page_count = cur_page_count + inc_page_count;
|
||||
uint32 old_size = NumBytesPerPage * cur_page_count;
|
||||
uint64 total_size = (uint64)NumBytesPerPage * total_page_count;
|
||||
|
||||
if (inc_page_count <= 0)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < cur_page_count /* integer overflow */
|
||||
|| total_page_count > max_page_count) {
|
||||
aot_set_exception(module_inst, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(mem_data_new = wasm_malloc((uint32)total_size))) {
|
||||
aot_set_exception(module_inst, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mem_data_new, mem_data_old, old_size);
|
||||
memset(mem_data_new + old_size, 0, (uint32)total_size - old_size);
|
||||
module_inst->mem_cur_page_count = total_page_count;
|
||||
module_inst->memory_data_size = (uint32)total_size;
|
||||
module_inst->memory_data.ptr = mem_data_new;
|
||||
module_inst->memory_data_end.ptr = mem_data_new + (uint32)total_size;
|
||||
|
||||
wasm_free(mem_data_old);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
|
||||
uint32 type1_idx, uint32 type2_idx)
|
||||
{
|
||||
WASMType *type1, *type2;
|
||||
AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
|
||||
|
||||
if (type1_idx >= module->func_type_count
|
||||
|| type2_idx >= module->func_type_count) {
|
||||
aot_set_exception(module_inst, "type index out of bounds");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type1_idx == type2_idx)
|
||||
return true;
|
||||
|
||||
type1 = module->func_types[type1_idx];
|
||||
type2 = module->func_types[type2_idx];
|
||||
|
||||
return wasm_type_equal(type1, type2);
|
||||
}
|
||||
434
core/iwasm/aot/aot_runtime.h
Normal file
434
core/iwasm/aot/aot_runtime.h
Normal file
@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _AOT_RUNTIME_H_
|
||||
#define _AOT_RUNTIME_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "../common/wasm_runtime_common.h"
|
||||
#include "../interpreter/wasm_runtime.h"
|
||||
#include "../compilation/aot.h"
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
#include "../compilation/aot_llvm.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AOT_MAGIC_NUMBER 0x746f6100
|
||||
#define AOT_CURRENT_VERSION 1
|
||||
|
||||
typedef enum AOTExceptionID {
|
||||
EXCE_UNREACHABLE = 0,
|
||||
EXCE_OUT_OF_MEMORY,
|
||||
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
|
||||
EXCE_INTEGER_OVERFLOW,
|
||||
EXCE_INTEGER_DIVIDE_BY_ZERO,
|
||||
EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||
EXCE_INVALID_FUNCTION_TYPE_INDEX,
|
||||
EXCE_INVALID_FUNCTION_INDEX,
|
||||
EXCE_UNDEFINED_ELEMENT,
|
||||
EXCE_UNINITIALIZED_ELEMENT,
|
||||
EXCE_CALL_UNLINKED_IMPORT_FUNC,
|
||||
EXCE_NUM,
|
||||
} AOTExceptionID;
|
||||
|
||||
typedef enum AOTSectionType {
|
||||
AOT_SECTION_TYPE_TARGET_INFO = 0,
|
||||
AOT_SECTION_TYPE_INIT_DATA,
|
||||
AOT_SECTION_TYPE_TEXT,
|
||||
AOT_SECTION_TYPE_FUNCTION,
|
||||
AOT_SECTION_TYPE_EXPORT,
|
||||
AOT_SECTION_TYPE_RELOCATION,
|
||||
AOT_SECTION_TYPE_SIGANATURE
|
||||
} AOTSectionType;
|
||||
|
||||
typedef struct AOTObjectDataSection {
|
||||
char *name;
|
||||
uint8 *data;
|
||||
uint32 size;
|
||||
} AOTObjectDataSection;
|
||||
|
||||
/* Relocation info */
|
||||
typedef struct AOTRelocation {
|
||||
uint64 relocation_offset;
|
||||
uint64 relocation_addend;
|
||||
uint32 relocation_type;
|
||||
char *symbol_name;
|
||||
/* index in the symbol offset field */
|
||||
uint32 symbol_index;
|
||||
} AOTRelocation;
|
||||
|
||||
/* Relocation Group */
|
||||
typedef struct AOTRelocationGroup {
|
||||
char *section_name;
|
||||
/* index in the symbol offset field */
|
||||
uint32 name_index;
|
||||
uint32 relocation_count;
|
||||
AOTRelocation *relocations;
|
||||
} AOTRelocationGroup;
|
||||
|
||||
typedef struct AOTModule {
|
||||
uint32 module_type;
|
||||
|
||||
/* memory info */
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
uint32 mem_init_data_count;
|
||||
AOTMemInitData **mem_init_data_list;
|
||||
|
||||
/* table info */
|
||||
uint32 table_size;
|
||||
uint32 table_init_data_count;
|
||||
AOTTableInitData **table_init_data_list;
|
||||
|
||||
/* function type info */
|
||||
uint32 func_type_count;
|
||||
AOTFuncType **func_types;
|
||||
|
||||
/* import global varaible info */
|
||||
uint32 import_global_count;
|
||||
AOTImportGlobal *import_globals;
|
||||
|
||||
/* global variable info */
|
||||
uint32 global_count;
|
||||
AOTGlobal *globals;
|
||||
|
||||
/* total global variable size */
|
||||
uint32 global_data_size;
|
||||
|
||||
/* import function info */
|
||||
uint32 import_func_count;
|
||||
AOTImportFunc *import_funcs;
|
||||
|
||||
/* function info */
|
||||
uint32 func_count;
|
||||
/* point to AOTed/JITed functions */
|
||||
void **func_ptrs;
|
||||
/* function type indexes */
|
||||
uint32 *func_type_indexes;
|
||||
|
||||
/* export function info */
|
||||
uint32 export_func_count;
|
||||
AOTExportFunc *export_funcs;
|
||||
|
||||
/* start function index, -1 denotes no start function */
|
||||
uint32 start_func_index;
|
||||
/* start function, point to AOTed/JITed function */
|
||||
void *start_function;
|
||||
|
||||
/* AOTed code, NULL for JIT mode */
|
||||
void *code;
|
||||
uint32 code_size;
|
||||
|
||||
/* data sections in AOT object file, including .data, .rodata
|
||||
* and .rodata.cstN. NULL for JIT mode. */
|
||||
AOTObjectDataSection *data_sections;
|
||||
uint32 data_section_count;
|
||||
|
||||
/* constant string set */
|
||||
HashMap *const_str_set;
|
||||
|
||||
/* is jit mode or not */
|
||||
bool is_jit_mode;
|
||||
|
||||
#if WASM_ENABLE_JIT
|
||||
WASMModule *wasm_module;
|
||||
AOTCompContext *comp_ctx;
|
||||
AOTCompData *comp_data;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIArguments wasi_args;
|
||||
bool is_wasi_module;
|
||||
#endif
|
||||
} AOTModule;
|
||||
|
||||
typedef union {
|
||||
uint64 _make_it_8_bytes_;
|
||||
void *ptr;
|
||||
} AOTPointer;
|
||||
|
||||
typedef struct AOTModuleInstance {
|
||||
uint32 module_type;
|
||||
|
||||
/* memory space info */
|
||||
uint32 mem_cur_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
uint32 memory_data_size;
|
||||
AOTPointer memory_data;
|
||||
AOTPointer memory_data_end;
|
||||
|
||||
/* heap space info */
|
||||
int32 heap_base_offset;
|
||||
uint32 heap_data_size;
|
||||
AOTPointer heap_data;
|
||||
AOTPointer heap_data_end;
|
||||
AOTPointer heap_handle;
|
||||
|
||||
/* global and table info */
|
||||
uint32 global_data_size;
|
||||
uint32 table_size;
|
||||
AOTPointer global_data;
|
||||
AOTPointer table_data;
|
||||
|
||||
/* funciton pointer array */
|
||||
AOTPointer func_ptrs;
|
||||
/* function type indexes */
|
||||
AOTPointer func_type_indexes;
|
||||
|
||||
/* The exception buffer for current thread. */
|
||||
char cur_exception[128];
|
||||
/* The custom data that can be set/get by
|
||||
* wasm_runtime_set_custom_data/wasm_runtime_get_custom_data */
|
||||
AOTPointer custom_data;
|
||||
/* The AOT module */
|
||||
AOTPointer aot_module;
|
||||
/* WASI context */
|
||||
AOTPointer wasi_ctx;
|
||||
|
||||
/* others */
|
||||
int32 temp_ret;
|
||||
uint32 llvm_stack;
|
||||
int32 DYNAMICTOP_PTR_offset;
|
||||
uint32 default_wasm_stack_size;
|
||||
|
||||
/* reserved */
|
||||
uint32 reserved[16];
|
||||
|
||||
union {
|
||||
uint64 _make_it_8_byte_aligned_;
|
||||
uint8 bytes[1];
|
||||
} global_table_heap_data;
|
||||
} AOTModuleInstance;
|
||||
|
||||
typedef AOTExportFunc AOTFunctionInstance;
|
||||
|
||||
/* Target info, read from ELF header of object file */
|
||||
typedef struct AOTTargetInfo {
|
||||
/* Binary type, elf32l/elf32b/elf64l/elf64b */
|
||||
uint32 bin_type;
|
||||
/* Object file type */
|
||||
uint16 e_type;
|
||||
/* Architecture */
|
||||
uint16 e_machine;
|
||||
/* Object file version */
|
||||
uint32 e_version;
|
||||
/* Processor-specific flags */
|
||||
uint32 e_flags;
|
||||
/* Reserved */
|
||||
uint32 reserved;
|
||||
/* Arch name */
|
||||
char arch[16];
|
||||
} AOTTargetInfo;
|
||||
|
||||
/**
|
||||
* Load a AOT module from aot file buffer
|
||||
* @param buf the byte buffer which contains the AOT file data
|
||||
* @param size the size of the buffer
|
||||
* @param error_buf output of the error info
|
||||
* @param error_buf_size the size of the error string
|
||||
*
|
||||
* @return return AOT module loaded, NULL if failed
|
||||
*/
|
||||
AOTModule*
|
||||
aot_load_from_aot_file(const uint8 *buf, uint32 size,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
/**
|
||||
* Load a AOT module from a specified AOT section list.
|
||||
*
|
||||
* @param section_list the section list which contains each section data
|
||||
* @param error_buf output of the error info
|
||||
* @param error_buf_size the size of the error string
|
||||
*
|
||||
* @return return AOT module loaded, NULL if failed
|
||||
*/
|
||||
AOTModule*
|
||||
aot_load_from_sections(AOTSection *section_list,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
/**
|
||||
* Convert WASM module to AOT module
|
||||
*
|
||||
* @param wasm_module the WASM module to convert
|
||||
* @param error_buf output of the error info
|
||||
* @param error_buf_size the size of the error string
|
||||
*
|
||||
* @return return AOT module loaded, NULL if failed
|
||||
*/
|
||||
AOTModule*
|
||||
aot_convert_wasm_module(WASMModule *wasm_module,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unload a AOT module.
|
||||
*
|
||||
* @param module the module to be unloaded
|
||||
*/
|
||||
void
|
||||
aot_unload(AOTModule *module);
|
||||
|
||||
/**
|
||||
* Instantiate a AOT module.
|
||||
*
|
||||
* @param module the AOT module to instantiate
|
||||
* @param heap_size the default heap size of the module instance, a heap will
|
||||
* be created besides the app memory space. Both wasm app and native
|
||||
* function can allocate memory from the heap. If heap_size is 0, the
|
||||
* default heap size will be used.
|
||||
* @param error_buf buffer to output the error info if failed
|
||||
* @param error_buf_size the size of the error buffer
|
||||
*
|
||||
* @return return the instantiated AOT module instance, NULL if failed
|
||||
*/
|
||||
AOTModuleInstance*
|
||||
aot_instantiate(AOTModule *module,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
/**
|
||||
* Deinstantiate a AOT module instance, destroy the resources.
|
||||
*
|
||||
* @param module_inst the AOT module instance to destroy
|
||||
*/
|
||||
void
|
||||
aot_deinstantiate(AOTModuleInstance *module_inst);
|
||||
|
||||
/**
|
||||
* Lookup an exported function in the AOT module instance.
|
||||
*
|
||||
* @param module_inst the module instance
|
||||
* @param name the name of the function
|
||||
* @param signature the signature of the function, use "i32"/"i64"/"f32"/"f64"
|
||||
* to represent the type of i32/i64/f32/f64, e.g. "(i32i64)" "(i32)f32"
|
||||
*
|
||||
* @return the function instance found
|
||||
*/
|
||||
AOTFunctionInstance*
|
||||
aot_lookup_function(const AOTModuleInstance *module_inst,
|
||||
const char *name, const char *signature);
|
||||
/**
|
||||
* Call the given AOT function of a AOT module instance with
|
||||
* arguments.
|
||||
*
|
||||
* @param exec_env the execution environment
|
||||
* @param function the function to be called
|
||||
* @param argc the number of arguments
|
||||
* @param argv the arguments. If the function method has return value,
|
||||
* the first (or first two in case 64-bit return value) element of
|
||||
* argv stores the return value of the called AOT function after this
|
||||
* function returns.
|
||||
*
|
||||
* @return true if success, false otherwise and exception will be thrown,
|
||||
* the caller can call aot_get_exception to get exception info.
|
||||
*/
|
||||
bool
|
||||
aot_call_function(WASMExecEnv *exec_env,
|
||||
AOTFunctionInstance *function,
|
||||
unsigned argc, uint32 argv[]);
|
||||
|
||||
bool
|
||||
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
|
||||
AOTFunctionInstance *function,
|
||||
unsigned argc, uint32 argv[]);
|
||||
/**
|
||||
* Set AOT module instance exception with exception string
|
||||
*
|
||||
* @param module the AOT module instance
|
||||
*
|
||||
* @param exception current exception string
|
||||
*/
|
||||
void
|
||||
aot_set_exception(AOTModuleInstance *module_inst,
|
||||
const char *exception);
|
||||
|
||||
void
|
||||
aot_set_exception_with_id(AOTModuleInstance *module_inst,
|
||||
uint32 id);
|
||||
|
||||
/**
|
||||
* Get exception info of the AOT module instance.
|
||||
*
|
||||
* @param module_inst the AOT module instance
|
||||
*
|
||||
* @return the exception string
|
||||
*/
|
||||
const char*
|
||||
aot_get_exception(AOTModuleInstance *module_inst);
|
||||
|
||||
/**
|
||||
* Clear exception info of the AOT module instance.
|
||||
*
|
||||
* @param module_inst the AOT module instance
|
||||
*/
|
||||
void
|
||||
aot_clear_exception(AOTModuleInstance *module_inst);
|
||||
|
||||
int32
|
||||
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size);
|
||||
|
||||
void
|
||||
aot_module_free(AOTModuleInstance *module_inst, int32 ptr);
|
||||
|
||||
int32
|
||||
aot_module_dup_data(AOTModuleInstance *module_inst,
|
||||
const char *src, uint32 size);
|
||||
|
||||
bool
|
||||
aot_validate_app_addr(AOTModuleInstance *module_inst,
|
||||
int32 app_offset, uint32 size);
|
||||
|
||||
|
||||
bool
|
||||
aot_validate_native_addr(AOTModuleInstance *module_inst,
|
||||
void *native_ptr, uint32 size);
|
||||
|
||||
void *
|
||||
aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset);
|
||||
|
||||
int32
|
||||
aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr);
|
||||
|
||||
bool
|
||||
aot_get_app_addr_range(AOTModuleInstance *module_inst,
|
||||
int32 app_offset,
|
||||
int32 *p_app_start_offset,
|
||||
int32 *p_app_end_offset);
|
||||
|
||||
bool
|
||||
aot_get_native_addr_range(AOTModuleInstance *module_inst,
|
||||
uint8 *native_ptr,
|
||||
uint8 **p_native_start_addr,
|
||||
uint8 **p_native_end_addr);
|
||||
|
||||
bool
|
||||
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count);
|
||||
|
||||
/**
|
||||
* Compare whether two wasm types are equal according to the indexs
|
||||
*
|
||||
* @param module_inst the AOT module instance
|
||||
* @param type1_idx index of the first wasm type
|
||||
* @param type2_idx index of the second wasm type
|
||||
*
|
||||
* @return true if equal, false otherwise
|
||||
*/
|
||||
bool
|
||||
aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
|
||||
uint32 type1_idx, uint32 type2_idx);
|
||||
|
||||
uint32
|
||||
aot_get_plt_table_size();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _AOT_RUNTIME_H_ */
|
||||
|
||||
13
core/iwasm/aot/iwasm_aot.cmake
Normal file
13
core/iwasm/aot/iwasm_aot.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (IWASM_AOT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_AOT=1)
|
||||
|
||||
include_directories (${IWASM_AOT_DIR})
|
||||
|
||||
file (GLOB c_source_all ${IWASM_AOT_DIR}/*.c)
|
||||
|
||||
set (IWASM_AOT_SOURCE ${c_source_all})
|
||||
|
||||
Reference in New Issue
Block a user