Merge main into dev/fast_jit

This commit is contained in:
Wenyong Huang 2022-05-18 20:35:13 +08:00
commit 4746eaa029
92 changed files with 2073 additions and 562 deletions

View File

@ -208,7 +208,7 @@ def main():
},
"xtensa": {
"repo": "https://github.com/espressif/llvm-project.git",
"branch": "xtensa_release_11.0.0",
"branch": "xtensa_release_13.0.0",
},
"default": {
"repo": "https://github.com/llvm/llvm-project.git",

View File

@ -8,7 +8,7 @@
#include "runtime_timer.h"
void
bool
init_wasm_timer();
void
exit_wasm_timer();

View File

@ -83,19 +83,36 @@ wakeup_modules_timer_thread(timer_ctx_t ctx)
os_mutex_unlock(&g_timer_ctx_list_mutex);
}
void
bool
init_wasm_timer()
{
korp_tid tm_tid;
bh_list_init(&g_timer_ctx_list);
os_cond_init(&g_timer_ctx_list_cond);
if (os_cond_init(&g_timer_ctx_list_cond) != 0) {
return false;
}
/* temp solution for: thread_modulers_timer_check thread
would recursive lock the mutex */
os_recursive_mutex_init(&g_timer_ctx_list_mutex);
if (os_recursive_mutex_init(&g_timer_ctx_list_mutex) != 0) {
goto fail1;
}
os_thread_create(&tm_tid, thread_modulers_timer_check, NULL,
BH_APPLET_PRESERVED_STACK_SIZE);
if (0
!= os_thread_create(&tm_tid, thread_modulers_timer_check, NULL,
BH_APPLET_PRESERVED_STACK_SIZE)) {
goto fail2;
}
return true;
fail2:
os_mutex_destroy(&g_timer_ctx_list_mutex);
fail1:
os_cond_destroy(&g_timer_ctx_list_cond);
return false;
}
void

View File

@ -309,7 +309,13 @@ add_sys_sensor(char *name, char *description, int instance,
g_sys_sensors = s;
}
os_mutex_init(&s->lock);
if (os_mutex_init(&s->lock) != 0) {
if (s->description) {
wasm_runtime_free(s->description);
}
wasm_runtime_free(s->name);
wasm_runtime_free(s);
}
return s;
}
@ -358,6 +364,7 @@ find_sensor_client(sys_sensor_t *sensor, unsigned int client_id,
return c;
}
else {
prev = c;
c = c->next;
}
}

View File

@ -59,7 +59,7 @@ check_sensor_timers();
void
reschedule_sensor_read();
void
bool
init_sensor_framework();
void
start_sensor_framework();

View File

@ -106,12 +106,18 @@ cb_wakeup_thread()
void
set_sensor_reshceduler(void (*callback)());
void
bool
init_sensor_framework()
{
// init the mutext and conditions
os_cond_init(&cond);
os_mutex_init(&mutex);
/* init the mutext and conditions */
if (os_cond_init(&cond) != 0) {
return false;
}
if (os_mutex_init(&mutex) != 0) {
os_cond_destroy(&cond);
return false;
}
set_sensor_reshceduler(cb_wakeup_thread);
@ -119,6 +125,8 @@ init_sensor_framework()
app_mgr_sensor_event_callback);
wasm_register_cleanup_callback(sensor_cleanup_callback);
return true;
}
void

View File

@ -264,15 +264,21 @@ aee_host_msg_callback(void *msg, uint32_t msg_len)
bool
app_manager_host_init(host_interface *interface)
{
os_mutex_init(&host_lock);
if (os_mutex_init(&host_lock) != 0) {
return false;
}
memset(&recv_ctx, 0, sizeof(recv_ctx));
host_commu.init = interface->init;
host_commu.send = interface->send;
host_commu.destroy = interface->destroy;
if (host_commu.init != NULL)
return host_commu.init();
if (host_commu.init != NULL) {
if (!host_commu.init()) {
os_mutex_destroy(&host_lock);
return false;
}
}
return true;
}

View File

@ -207,10 +207,12 @@ app_instance_queue_callback(void *queue_msg, void *arg)
wasm_module_inst_t inst = (wasm_module_inst_t)arg;
module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst);
wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
int message_type = bh_message_type(queue_msg);
wasm_data *wasm_app_data;
int message_type;
bh_assert(m_data);
wasm_app_data = (wasm_data *)m_data->internal_data;
message_type = bh_message_type(queue_msg);
if (message_type < BASE_EVENT_MAX) {
switch (message_type) {
@ -410,16 +412,15 @@ wasm_app_prepare_wasi_dir(wasm_module_t module, const char *module_name,
p += module_name_len;
*p++ = '\0';
/* Create a wasi dir for the module */
if (stat(wasi_dir_buf, &st) == 0) {
/* exist, but is a regular file, not a dir */
if (st.st_mode & S_IFREG)
return false;
}
else {
/* not exist, create it */
if (mkdir(wasi_dir_buf, 0777) != 0)
return false;
if (mkdir(wasi_dir_buf, 0777) != 0) {
if (errno == EEXIST) {
/* Failed due to dir already exist */
if ((stat(wasi_dir_buf, &st) == 0) && (st.st_mode & S_IFDIR)) {
return true;
}
}
return false;
}
return true;
@ -491,9 +492,16 @@ wasm_app_routine(void *arg)
fail2:
/* Call WASM app onDestroy() method if there is */
func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()");
if (func_onDestroy)
wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0,
NULL);
if (func_onDestroy) {
if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0,
NULL)) {
const char *exception = wasm_runtime_get_exception(inst);
bh_assert(exception);
app_manager_printf("Got exception running WASM code: %s\n",
exception);
wasm_runtime_clear_exception(inst);
}
}
fail1:

View File

@ -261,48 +261,34 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
char *str;
uint16 str_len;
CHECK_BUF(p, p_end, 1);
if (*p & 0x80) {
/* The string has been adjusted */
str = (char *)++p;
/* Ensure the whole string is in range */
do {
CHECK_BUF(p, p_end, 1);
} while (*p++ != '\0');
read_uint16(p, p_end, str_len);
CHECK_BUF(p, p_end, str_len);
if (str_len == 0) {
str = "";
}
else if (p[str_len - 1] == '\0') {
/* The string is terminated with '\0', use it directly */
str = (char *)p;
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading,
we use the 2 bytes of size to adjust the string:
move string 2 byte backward and then append '\0' */
str = (char *)(p - 2);
bh_memmove_s(str, (uint32)(str_len + 1), p, (uint32)str_len);
str[str_len] = '\0';
}
else {
/* The string hasn't been adjusted */
read_uint16(p, p_end, str_len);
CHECK_BUF(p, p_end, str_len);
if (str_len == 0) {
str = "";
/* Load from sections, the file buffer cannot be reffered to
after loading, we must create another string and insert it
into const string set */
if (!(str = const_str_set_insert((uint8 *)p, str_len, module, error_buf,
error_buf_size))) {
goto fail;
}
else if (p[str_len - 1] == '\0') {
/* The string is terminated with '\0', use it directly */
str = (char *)p;
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading,
we use the 2 bytes of size to adjust the string:
mark the flag with the highest bit of size[0],
move string 1 byte backward and then append '\0' */
*(p - 2) |= 0x80;
bh_memmove_s(p - 1, (uint32)(str_len + 1), p, (uint32)str_len);
p[str_len - 1] = '\0';
str = (char *)(p - 1);
}
else {
/* Load from sections, the file buffer cannot be reffered to
after loading, we must create another string and insert it
into const string set */
if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
error_buf, error_buf_size))) {
goto fail;
}
}
p += str_len;
}
p += str_len;
*p_buf = p;
return str;
@ -1850,7 +1836,9 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
|| !strcmp(symbol, ".rdata")
|| !strcmp(symbol, ".rodata")
/* ".rodata.cst4/8/16/.." */
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))) {
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
/* ".rodata.strn.m" */
|| !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))) {
symbol_addr = get_data_section_addr(module, symbol, NULL);
if (!symbol_addr) {
set_error_buf_v(error_buf, error_buf_size,
@ -2054,6 +2042,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
uint8 *symbol_buf, *symbol_buf_end;
int map_prot, map_flags;
bool ret = false;
char **symbols = NULL;
read_uint32(buf, buf_end, symbol_count);
@ -2074,6 +2063,14 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
goto fail;
}
if (symbol_count > 0) {
symbols = loader_malloc((uint64)sizeof(*symbols) * symbol_count,
error_buf, error_buf_size);
if (symbols == NULL) {
goto fail;
}
}
#if defined(BH_PLATFORM_WINDOWS)
buf = symbol_buf_end;
read_uint32(buf, buf_end, group_count);
@ -2208,7 +2205,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
for (i = 0, group = groups; i < group_count; i++, group++) {
AOTRelocation *relocation;
uint32 name_index;
uint8 *name_addr;
/* section name address is 4 bytes aligned. */
buf = (uint8 *)align_ptr(buf, sizeof(uint32));
@ -2220,8 +2216,12 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
goto fail;
}
name_addr = symbol_buf + symbol_offsets[name_index];
read_string(name_addr, buf_end, group->section_name);
if (symbols[name_index] == NULL) {
uint8 *name_addr = symbol_buf + symbol_offsets[name_index];
read_string(name_addr, buf_end, symbols[name_index]);
}
group->section_name = symbols[name_index];
read_uint32(buf, buf_end, group->relocation_count);
@ -2236,7 +2236,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
/* Load each relocation */
for (j = 0; j < group->relocation_count; j++, relocation++) {
uint32 symbol_index;
uint8 *symbol_addr;
if (sizeof(void *) == 8) {
read_uint64(buf, buf_end, relocation->relocation_offset);
@ -2258,8 +2257,12 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
goto fail;
}
symbol_addr = symbol_buf + symbol_offsets[symbol_index];
read_string(symbol_addr, buf_end, relocation->symbol_name);
if (symbols[symbol_index] == NULL) {
uint8 *symbol_addr = symbol_buf + symbol_offsets[symbol_index];
read_string(symbol_addr, buf_end, symbols[symbol_index]);
}
relocation->symbol_name = symbols[symbol_index];
}
if (!strcmp(group->section_name, ".rel.text")
@ -2314,7 +2317,10 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|| !strcmp(data_section->name, ".rodata")
/* ".rodata.cst4/8/16/.." */
|| !strncmp(data_section->name, ".rodata.cst",
strlen(".rodata.cst"))) {
strlen(".rodata.cst"))
/* ".rodata.strn.m" */
|| !strncmp(data_section->name, ".rodata.str",
strlen(".rodata.str"))) {
os_mprotect(data_section->data, data_section->size, map_prot);
}
}
@ -2322,6 +2328,9 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
ret = true;
fail:
if (symbols) {
wasm_runtime_free(symbols);
}
if (groups) {
for (i = 0, group = groups; i < group_count; i++, group++)
if (group->relocations)

View File

@ -14,6 +14,22 @@
#include "../libraries/thread-mgr/thread_manager.h"
#endif
/*
* Note: These offsets need to match the values hardcoded in
* AoT compilation code: aot_create_func_context, check_suspend_flags.
*/
bh_static_assert(offsetof(WASMExecEnv, module_inst) == 2 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, argv_buf) == 3 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, native_stack_boundary)
== 4 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, suspend_flags) == 5 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, aux_stack_boundary)
== 6 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, aux_stack_bottom)
== 7 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, native_symbol) == 8 * sizeof(uintptr_t));
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
@ -638,6 +654,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
/* Get default memory instance */
memory_inst = aot_get_default_memory(module_inst);
if (!memory_inst) {
/* Ignore setting memory init data if no memory inst is created */
return true;
}
for (i = 0; i < module->mem_init_data_count; i++) {
data_seg = module->mem_init_data_list[i];
@ -1778,9 +1798,9 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
malloc_func =
aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig);
bh_assert(malloc_func);
if (!execute_malloc_function(module_inst, malloc_func, retain_func,
size, &offset)) {
if (!malloc_func
|| !execute_malloc_function(module_inst, malloc_func, retain_func,
size, &offset)) {
return 0;
}
addr = offset ? (uint8 *)memory_inst->memory_data.ptr + offset : NULL;
@ -1873,8 +1893,8 @@ aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
if (!free_func && module->retain_func_index != (uint32)-1)
free_func = aot_lookup_function(module_inst, "__unpin", "(i)i");
bh_assert(free_func);
execute_free_function(module_inst, free_func, ptr);
if (free_func)
execute_free_function(module_inst, free_func, ptr);
}
}
}
@ -2614,7 +2634,7 @@ aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size)
static void
const_string_node_size_cb(void *key, void *value, void *p_const_string_size)
{
uint32 const_string_size = *(uint32 *)p_const_string_size;
uint32 const_string_size = 0;
const_string_size += bh_hash_map_get_elem_struct_size();
const_string_size += strlen((const char *)value) + 1;
*(uint32 *)p_const_string_size += const_string_size;
@ -2893,6 +2913,7 @@ aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
#endif /* WASM_ENABLE_REF_TYPES != 0 */
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
static const char *
lookup_func_name(const char **func_names, uint32 *func_indexes,
uint32 func_index_count, uint32 func_index)
@ -2913,6 +2934,7 @@ lookup_func_name(const char **func_names, uint32 *func_indexes,
return NULL;
}
#endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
static const char *
get_func_name_from_index(const AOTModuleInstance *module_inst,

View File

@ -8,6 +8,8 @@
#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */
#define R_ARM_JMP24 29 /* PC relative 24 bit (B/BL<cond>). */
#define R_ARM_ABS32 2 /* Direct 32 bit */
#define R_ARM_MOVW_ABS_NC 43
#define R_ARM_MOVT_ABS 44
/* clang-format off */
void __adddf3();
@ -339,6 +341,21 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
+ (intptr_t)reloc_addend;
break;
}
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
{
uintptr_t *loc;
uintptr_t addr;
CHECK_RELOC_OFFSET(sizeof(void *));
loc = (uintptr_t *)(target_section_addr + (uint32)reloc_offset);
addr = (uintptr_t)symbol_addr + (intptr_t)reloc_addend;
if (reloc_type == R_ARM_MOVT_ABS) {
addr >>= 16;
}
*loc = ((*loc) & 0xfff0f000) | ((addr << 4) & 0x000f0000)
| (addr & 0x00000fff);
break;
}
default:
if (error_buf != NULL)

View File

@ -10,6 +10,9 @@
#if WASM_ENABLE_AOT != 0
#include "../aot/aot_runtime.h"
#endif
#if WASM_ENABLE_THREAD_MGR != 0
#include "../libraries/thread-mgr/thread_manager.h"
#endif
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
@ -76,9 +79,8 @@ check_main_func_type(const WASMType *type)
return true;
}
bool
wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
char *argv[])
static bool
execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
{
WASMFunctionInstanceCommon *func;
WASMType *func_type = NULL;
@ -203,6 +205,41 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
return ret;
}
bool
wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
char *argv[])
{
bool ret;
#if WASM_ENABLE_THREAD_MGR != 0
WASMCluster *cluster;
#endif
#if WASM_ENABLE_THREAD_MGR != 0 || WASM_ENABLE_MEMORY_PROFILING != 0
WASMExecEnv *exec_env;
#endif
ret = execute_main(module_inst, argc, argv);
#if WASM_ENABLE_THREAD_MGR != 0
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) {
wasm_cluster_wait_for_all_except_self(cluster, exec_env);
}
#endif
#if WASM_ENABLE_MEMORY_PROFILING != 0
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
if (exec_env) {
wasm_runtime_dump_mem_consumption(exec_env);
}
#endif
#if WASM_ENABLE_PERF_PROFILING != 0
wasm_runtime_dump_perf_profiling(module_inst);
#endif
return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false;
}
#if WASM_ENABLE_MULTI_MODULE != 0
static WASMModuleInstance *
get_sub_module_inst(const WASMModuleInstance *parent_module_inst,
@ -351,9 +388,9 @@ union ieee754_double {
} ieee;
};
bool
wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
const char *name, int32 argc, char *argv[])
static bool
execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
int32 argc, char *argv[])
{
WASMFunctionInstanceCommon *target_func;
WASMModuleInstanceCommon *target_inst;
@ -689,3 +726,38 @@ fail:
os_printf("%s\n", exception);
return false;
}
bool
wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
const char *name, int32 argc, char *argv[])
{
bool ret;
#if WASM_ENABLE_THREAD_MGR != 0
WASMCluster *cluster;
#endif
#if WASM_ENABLE_THREAD_MGR != 0 || WASM_ENABLE_MEMORY_PROFILING != 0
WASMExecEnv *exec_env;
#endif
ret = execute_func(module_inst, name, argc, argv);
#if WASM_ENABLE_THREAD_MGR != 0
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) {
wasm_cluster_wait_for_all_except_self(cluster, exec_env);
}
#endif
#if WASM_ENABLE_MEMORY_PROFILING != 0
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
if (exec_env) {
wasm_runtime_dump_mem_consumption(exec_env);
}
#endif
#if WAMR_ENABLE_PERF_PROFILING != 0
wasm_runtime_dump_perf_profiling(module_inst);
#endif
return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false;
}

View File

@ -142,6 +142,9 @@ failed: \
void wasm_##name##_vec_copy(wasm_##name##_vec_t *out, \
const wasm_##name##_vec_t *src) \
{ \
if (!src) { \
return; \
} \
wasm_##name##_vec_new(out, src->size, src->data); \
} \
void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \
@ -186,6 +189,10 @@ failed: \
const wasm_##name##_vec_t *src) \
{ \
size_t i = 0; \
\
if (!out) { \
return; \
} \
memset(out, 0, sizeof(Vector)); \
\
if (!src || !src->size) { \
@ -214,7 +221,7 @@ failed: \
if (!v) { \
return; \
} \
for (i = 0; i != v->num_elems; ++i) { \
for (i = 0; i != v->num_elems && v->data; ++i) { \
elem_destroy_func(*(v->data + i)); \
} \
bh_vector_destroy((Vector *)v); \
@ -381,7 +388,8 @@ wasm_store_new(wasm_engine_t *engine)
DEFAULT_VECTOR_INIT_LENGTH);
if (!(store->foreigns = malloc_internal(sizeof(Vector)))
|| !(bh_vector_init(store->foreigns, 24, sizeof(Vector *), true))) {
|| !(bh_vector_init(store->foreigns, 24, sizeof(wasm_foreign_t *),
true))) {
goto failed;
}
@ -467,6 +475,14 @@ wasm_valtype_new(wasm_valkind_t kind)
{
wasm_valtype_t *val_type;
if (kind > WASM_F64 && WASM_FUNCREF != kind
#if WASM_ENABLE_REF_TYPES != 0
&& WASM_ANYREF != kind
#endif
) {
return NULL;
}
if (!(val_type = malloc_internal(sizeof(wasm_valtype_t)))) {
return NULL;
}
@ -558,14 +574,6 @@ wasm_functype_new(own wasm_valtype_vec_t *params,
{
wasm_functype_t *type = NULL;
if (!params) {
return NULL;
}
if (!results) {
return NULL;
}
if (!(type = malloc_internal(sizeof(wasm_functype_t)))) {
goto failed;
}
@ -576,14 +584,18 @@ wasm_functype_new(own wasm_valtype_vec_t *params,
if (!(type->params = malloc_internal(sizeof(wasm_valtype_vec_t)))) {
goto failed;
}
bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params,
sizeof(wasm_valtype_vec_t));
if (params) {
bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params,
sizeof(wasm_valtype_vec_t));
}
if (!(type->results = malloc_internal(sizeof(wasm_valtype_vec_t)))) {
goto failed;
}
bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results,
sizeof(wasm_valtype_vec_t));
if (results) {
bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results,
sizeof(wasm_valtype_vec_t));
}
return type;
@ -775,7 +787,15 @@ wasm_tabletype_new(own wasm_valtype_t *val_type, const wasm_limits_t *limits)
{
wasm_tabletype_t *table_type = NULL;
if (!val_type) {
if (!val_type || !limits) {
return NULL;
}
if (wasm_valtype_kind(val_type) != WASM_FUNCREF
#if WASM_ENABLE_REF_TYPES != 0
&& wasm_valtype_kind(val_type) != WASM_ANYREF
#endif
) {
return NULL;
}
@ -979,7 +999,7 @@ wasm_externtype_copy(const wasm_externtype_t *src)
COPY_EXTERNTYPE(TABLE, tabletype)
#undef COPY_EXTERNTYPE
default:
LOG_WARNING("%s meets unsupported kind", __FUNCTION__,
LOG_WARNING("%s meets unsupported kind %u", __FUNCTION__,
src->extern_kind);
break;
}
@ -1007,7 +1027,8 @@ wasm_externtype_delete(wasm_externtype_t *extern_type)
wasm_tabletype_delete(wasm_externtype_as_tabletype(extern_type));
break;
default:
LOG_WARNING("%s meets unsupported type", __FUNCTION__, extern_type);
LOG_WARNING("%s meets unsupported type %u", __FUNCTION__,
wasm_externtype_kind(extern_type));
break;
}
}
@ -1019,6 +1040,10 @@ wasm_importtype_new(own wasm_byte_vec_t *module_name,
{
wasm_importtype_t *import_type = NULL;
if (!module_name || !field_name || !extern_type) {
return NULL;
}
if (!(import_type = malloc_internal(sizeof(wasm_importtype_t)))) {
return NULL;
}
@ -1055,6 +1080,7 @@ wasm_importtype_delete(own wasm_importtype_t *import_type)
DEINIT_VEC(import_type->module_name, wasm_byte_vec_delete);
DEINIT_VEC(import_type->name, wasm_byte_vec_delete);
wasm_externtype_delete(import_type->extern_type);
import_type->extern_type = NULL;
wasm_runtime_free(import_type);
}
@ -1134,6 +1160,10 @@ wasm_exporttype_new(own wasm_byte_vec_t *name,
{
wasm_exporttype_t *export_type = NULL;
if (!name || !extern_type) {
return NULL;
}
if (!(export_type = malloc_internal(sizeof(wasm_exporttype_t)))) {
return NULL;
}
@ -1366,7 +1396,7 @@ wasm_ref_copy(const wasm_ref_t *src)
void
wasm_ref_delete(own wasm_ref_t *ref)
{
if (!ref)
if (!ref || !ref->store)
return;
DELETE_HOST_INFO(ref);
@ -1619,7 +1649,7 @@ wasm_trap_new(wasm_store_t *store, const wasm_message_t *message)
{
wasm_trap_t *trap;
if (!store || !message) {
if (!store) {
return NULL;
}
@ -1627,7 +1657,10 @@ wasm_trap_new(wasm_store_t *store, const wasm_message_t *message)
return NULL;
}
INIT_VEC(trap->message, wasm_byte_vec_new, message->size, message->data);
if (message) {
INIT_VEC(trap->message, wasm_byte_vec_new, message->size,
message->data);
}
return trap;
failed:
@ -2279,7 +2312,7 @@ wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out)
}
default:
{
LOG_WARNING("%s meets unsupported type", __FUNCTION__,
LOG_WARNING("%s meets unsupported type %u", __FUNCTION__,
export->kind);
break;
}
@ -2310,6 +2343,10 @@ wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
{
wasm_func_t *func = NULL;
if (!type) {
goto failed;
}
if (!(func = malloc_internal(sizeof(wasm_func_t)))) {
goto failed;
}
@ -2334,6 +2371,10 @@ wasm_func_new_with_env_basic(wasm_store_t *store, const wasm_functype_t *type,
{
wasm_func_t *func = NULL;
if (!type) {
goto failed;
}
if (!(func = malloc_internal(sizeof(wasm_func_t)))) {
goto failed;
}
@ -2358,6 +2399,9 @@ wasm_func_new(wasm_store_t *store, const wasm_functype_t *type,
wasm_func_callback_t callback)
{
bh_assert(singleton_engine);
if (!callback) {
return NULL;
}
return wasm_func_new_basic(store, type, callback);
}
@ -2367,6 +2411,9 @@ wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *type,
void (*finalizer)(void *))
{
bh_assert(singleton_engine);
if (!callback) {
return NULL;
}
return wasm_func_new_with_env_basic(store, type, callback, env, finalizer);
}
@ -2572,7 +2619,7 @@ argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs,
return true;
}
if (!results || !results->num_elems || !results->size || !results->data) {
if (!results || !results->size || !results->data) {
return false;
}
@ -2640,7 +2687,22 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
WASMExecEnv *exec_env = NULL;
size_t param_count, result_count, alloc_count;
bh_assert(func && func->type && func->inst_comm_rt);
if (!func) {
return NULL;
}
if (!func->inst_comm_rt) {
wasm_name_t message = { 0 };
wasm_trap_t *trap;
wasm_name_new_from_string(&message, "failed to call unlinked function");
trap = wasm_trap_new(func->store, &message);
wasm_byte_vec_delete(&message);
return trap;
}
bh_assert(func->type);
#if WASM_ENABLE_INTERP != 0
if (func->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
@ -2765,6 +2827,10 @@ wasm_global_new(wasm_store_t *store, const wasm_globaltype_t *global_type,
bh_assert(singleton_engine);
if (!global_type || !init) {
goto failed;
}
global = malloc_internal(sizeof(wasm_global_t));
if (!global) {
goto failed;
@ -2952,7 +3018,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
void
wasm_global_set(wasm_global_t *global, const wasm_val_t *v)
{
if (!global || !v) {
if (!global || !v || !global->inst_comm_rt) {
return;
}
@ -2986,6 +3052,10 @@ wasm_global_get(const wasm_global_t *global, wasm_val_t *out)
return;
}
if (!global->inst_comm_rt) {
return;
}
memset(out, 0, sizeof(wasm_val_t));
#if WASM_ENABLE_INTERP != 0
@ -3276,7 +3346,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
{
uint32 ref_idx = NULL_REF;
if (!table) {
if (!table || !table->inst_comm_rt) {
return NULL;
}
@ -3336,7 +3406,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
uint32 *p_ref_idx = NULL;
uint32 function_count = 0;
if (!table) {
if (!table || !table->inst_comm_rt) {
return false;
}
@ -3417,7 +3487,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
wasm_table_size_t
wasm_table_size(const wasm_table_t *table)
{
if (!table) {
if (!table || !table->inst_comm_rt) {
return 0;
}
@ -3473,6 +3543,10 @@ wasm_memory_new_basic(wasm_store_t *store, const wasm_memorytype_t *type)
{
wasm_memory_t *memory = NULL;
if (!type) {
goto failed;
}
if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) {
goto failed;
}
@ -3606,8 +3680,13 @@ wasm_memory_type(const wasm_memory_t *memory)
byte_t *
wasm_memory_data(wasm_memory_t *memory)
{
WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt;
WASMModuleInstanceCommon *module_inst_comm;
if (!memory || !memory->inst_comm_rt) {
return NULL;
}
module_inst_comm = memory->inst_comm_rt;
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *module_inst =
@ -3638,8 +3717,13 @@ wasm_memory_data(wasm_memory_t *memory)
size_t
wasm_memory_data_size(const wasm_memory_t *memory)
{
WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt;
WASMModuleInstanceCommon *module_inst_comm;
if (!memory || !memory->inst_comm_rt) {
return 0;
}
module_inst_comm = memory->inst_comm_rt;
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *module_inst =
@ -3670,8 +3754,13 @@ wasm_memory_data_size(const wasm_memory_t *memory)
wasm_memory_pages_t
wasm_memory_size(const wasm_memory_t *memory)
{
WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt;
WASMModuleInstanceCommon *module_inst_comm;
if (!memory || !memory->inst_comm_rt) {
return 0;
}
module_inst_comm = memory->inst_comm_rt;
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *module_inst =
@ -3715,7 +3804,6 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp,
uint16 func_idx_rt, wasm_func_t *import)
{
WASMImport *imported_func_interp = NULL;
wasm_func_t *cloned = NULL;
bh_assert(inst && module_interp && import);
bh_assert(func_idx_rt < module_interp->import_function_count);
@ -3724,15 +3812,6 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp,
imported_func_interp = module_interp->import_functions + func_idx_rt;
bh_assert(imported_func_interp);
if (!(cloned = wasm_func_copy(import))) {
return false;
}
if (!bh_vector_append((Vector *)inst->imports, &cloned)) {
wasm_func_delete(cloned);
return false;
}
imported_func_interp->u.function.call_conv_wasm_c_api = true;
imported_func_interp->u.function.wasm_c_api_with_env = import->with_env;
if (import->with_env) {
@ -3936,30 +4015,22 @@ aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot,
uint32 import_func_idx_rt, wasm_func_t *import)
{
AOTImportFunc *import_aot_func = NULL;
wasm_func_t *cloned = NULL;
bh_assert(inst && module_aot && import);
import_aot_func = module_aot->import_funcs + import_func_idx_rt;
bh_assert(import_aot_func);
if (!(cloned = wasm_func_copy(import))) {
return false;
}
if (!bh_vector_append((Vector *)inst->imports, &cloned)) {
wasm_func_delete(cloned);
return false;
}
import_aot_func->call_conv_wasm_c_api = true;
import_aot_func->wasm_c_api_with_env = import->with_env;
if (import->with_env) {
import_aot_func->func_ptr_linked = import->u.cb_env.cb;
import_aot_func->attachment = import->u.cb_env.env;
}
else
else {
import_aot_func->func_ptr_linked = import->u.cb;
import_aot_func->attachment = NULL;
}
import->func_idx_rt = import_func_idx_rt;
return true;
@ -4188,14 +4259,11 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
}
/* link module and imports */
if (imports) {
if (imports && imports->num_elems) {
#if WASM_ENABLE_INTERP != 0
if ((*module)->module_type == Wasm_Module_Bytecode) {
import_count = MODULE_INTERP(module)->import_count;
INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized,
import_count);
if (import_count) {
uint32 actual_link_import_count =
interp_link(instance, MODULE_INTERP(module),
@ -4217,9 +4285,6 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
+ MODULE_AOT(module)->import_memory_count
+ MODULE_AOT(module)->import_table_count;
INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized,
import_count);
if (import_count) {
import_count = aot_link(instance, MODULE_AOT(module),
(wasm_extern_t **)imports->data);
@ -4344,7 +4409,6 @@ wasm_instance_delete_internal(wasm_instance_t *instance)
return;
}
DEINIT_VEC(instance->imports, wasm_extern_vec_delete);
DEINIT_VEC(instance->exports, wasm_extern_vec_delete);
if (instance->inst_comm_rt) {

View File

@ -206,7 +206,6 @@ struct wasm_extern_t {
struct wasm_instance_t {
wasm_store_t *store;
wasm_extern_vec_t *imports;
wasm_extern_vec_t *exports;
struct wasm_host_info host_info;
WASMModuleInstanceCommon *inst_comm_rt;

View File

@ -54,7 +54,6 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
if (!(exec_env->current_status = wasm_cluster_create_exenv_status()))
goto fail4;
#endif
#endif
exec_env->module_inst = module_inst;

View File

@ -109,6 +109,9 @@ typedef struct WASMExecEnv {
korp_cond wait_cond;
/* the count of threads which are joining current thread */
uint32 wait_count;
/* whether current thread is detached */
bool thread_is_detached;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
@ -188,8 +191,12 @@ wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
bh_assert(!(size & 3));
/* The outs area size cannot be larger than the frame size, so
multiplying by 2 is enough. */
/* For classic interpreter, the outs area doesn't contain the const cells,
its size cannot be larger than the frame size, so here checking stack
overflow with multiplying by 2 is enough. For fast interpreter, since
the outs area contains const cells, its size may be larger than current
frame size, we should check again before putting the function arguments
into the outs area. */
if (addr + size * 2 > exec_env->wasm_stack.s.top_boundary) {
/* WASM stack overflow. */
return NULL;

View File

@ -86,7 +86,7 @@ wasm_runtime_memory_pool_size()
if (memory_mode == MEMORY_MODE_POOL)
return global_pool_size;
else
return 1 * BH_GB;
return UINT32_MAX;
}
static inline void *

View File

@ -20,6 +20,9 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
void
wasm_runtime_memory_destroy();
unsigned
wasm_runtime_memory_pool_size();
#ifdef __cplusplus
}
#endif

View File

@ -32,6 +32,28 @@
#endif
#include "../common/wasm_c_api_internal.h"
/**
* For runtime build, BH_MALLOC/BH_FREE should be defined as
* wasm_runtime_malloc/wasm_runtime_free.
*/
#define CHECK(a) CHECK1(a)
#define CHECK1(a) SHOULD_BE_##a
#define SHOULD_BE_wasm_runtime_malloc 1
#if !CHECK(BH_MALLOC)
#error unexpected BH_MALLOC
#endif
#undef SHOULD_BE_wasm_runtime_malloc
#define SHOULD_BE_wasm_runtime_free 1
#if !CHECK(BH_FREE)
#error unexpected BH_FREE
#endif
#undef SHOULD_BE_wasm_runtime_free
#undef CHECK
#undef CHECK1
#if WASM_ENABLE_MULTI_MODULE != 0
/**
* A safety insurance to prevent
@ -824,26 +846,28 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
{
WASMModuleCommon *module_common;
#if WASM_ENABLE_INTERP != 0
if (!is_aot) {
#if WASM_ENABLE_INTERP != 0
module_common = (WASMModuleCommon *)wasm_load_from_sections(
section_list, error_buf, error_buf_size);
return register_module_with_null_name(module_common, error_buf,
error_buf_size);
}
#endif
}
else {
#if WASM_ENABLE_AOT != 0
if (is_aot) {
module_common = (WASMModuleCommon *)aot_load_from_sections(
section_list, error_buf, error_buf_size);
return register_module_with_null_name(module_common, error_buf,
error_buf_size);
}
#endif
}
#if WASM_ENABLE_INTERP == 0 || WASM_ENABLE_AOT == 0
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: invalid section list type");
return NULL;
#endif
}
void
@ -1268,7 +1292,7 @@ wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
}
if (!need_param_transform) {
bh_memcpy_s(new_argv, size, argv, size);
bh_memcpy_s(new_argv, (uint32)size, argv, (uint32)size);
}
else {
for (param_i = 0; param_i < func_type->param_count && argv_i < argc
@ -1328,7 +1352,7 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
bh_assert((argv && ret_argv) || (argc == 0));
if (argv == ret_argv || argc == 0) {
if (argv == ret_argv) {
/* no need to transfrom externref results */
return true;
}

View File

@ -224,17 +224,22 @@ acquire_wait_info(void *address, bool create)
AtomicWaitInfo *wait_info = NULL;
bh_list_status ret;
os_mutex_lock(&shared_memory_list_lock);
if (address)
wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address);
if (!create)
if (!create) {
os_mutex_unlock(&shared_memory_list_lock);
return wait_info;
}
/* No wait info on this address, create new info */
if (!wait_info) {
if (!(wait_info = (AtomicWaitInfo *)wasm_runtime_malloc(
sizeof(AtomicWaitInfo))))
return NULL;
sizeof(AtomicWaitInfo)))) {
goto fail1;
}
memset(wait_info, 0, sizeof(AtomicWaitInfo));
/* init wait list */
@ -244,20 +249,30 @@ acquire_wait_info(void *address, bool create)
/* init wait list lock */
if (0 != os_mutex_init(&wait_info->wait_list_lock)) {
wasm_runtime_free(wait_info);
return NULL;
goto fail2;
}
if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) {
os_mutex_destroy(&wait_info->wait_list_lock);
wasm_runtime_free(wait_info);
return NULL;
goto fail3;
}
}
os_mutex_unlock(&shared_memory_list_lock);
bh_assert(wait_info);
(void)ret;
return wait_info;
fail3:
os_mutex_destroy(&wait_info->wait_list_lock);
fail2:
wasm_runtime_free(wait_info);
fail1:
os_mutex_unlock(&shared_memory_list_lock);
return NULL;
}
static void
@ -285,10 +300,14 @@ destroy_wait_info(void *wait_info)
static void
release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address)
{
os_mutex_lock(&shared_memory_list_lock);
if (wait_info->wait_list->len == 0) {
bh_hash_map_remove(wait_map_, address, NULL, NULL);
destroy_wait_info(wait_info);
}
os_mutex_unlock(&shared_memory_list_lock);
}
uint32
@ -405,8 +424,9 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
uint32 notify_result;
AtomicWaitInfo *wait_info;
/* Nobody wait on this address */
wait_info = acquire_wait_info(address, false);
/* Nobody wait on this address */
if (!wait_info)
return 0;
@ -414,7 +434,5 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
notify_result = notify_wait_list(wait_info->wait_list, count);
os_mutex_unlock(&wait_info->wait_list_lock);
release_wait_info(wait_map, wait_info, address);
return notify_result;
}

View File

@ -276,8 +276,13 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
aot_set_last_error("allocate memory failed.");
goto fail;
}
#if WASM_ENABLE_FAST_INTERP != 0
for (i = 0; i <= br_count; i++)
read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]);
#else
for (i = 0; i <= br_count; i++)
br_depths[i] = *frame_ip++;
#endif
if (!aot_compile_op_br_table(comp_ctx, func_ctx, br_depths,
br_count, &frame_ip)) {
@ -288,6 +293,35 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
wasm_runtime_free(br_depths);
break;
#if WASM_ENABLE_FAST_INTERP == 0
case EXT_OP_BR_TABLE_CACHE:
{
BrTableCache *node = bh_list_first_elem(
comp_ctx->comp_data->wasm_module->br_table_cache_list);
BrTableCache *node_next;
uint8 *p_opcode = frame_ip - 1;
read_leb_uint32(frame_ip, frame_ip_end, br_count);
while (node) {
node_next = bh_list_elem_next(node);
if (node->br_table_op_addr == p_opcode) {
br_depths = node->br_depths;
if (!aot_compile_op_br_table(comp_ctx, func_ctx,
br_depths, br_count,
&frame_ip)) {
return false;
}
break;
}
node = node_next;
}
bh_assert(node);
break;
}
#endif
case WASM_OP_RETURN:
if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
return false;
@ -2636,7 +2670,7 @@ apply_func_passes(AOTCompContext *comp_ctx)
return true;
}
#if WASM_ENABLE_LLVM_LEGACY_PM != 0
#if WASM_ENABLE_LLVM_LEGACY_PM != 0 || LLVM_VERSION_MAJOR < 12
static bool
apply_lto_passes(AOTCompContext *comp_ctx)
{
@ -2675,7 +2709,7 @@ apply_lto_passes(AOTCompContext *comp_ctx)
LLVMPassManagerBuilderDispose(pass_mgr_builder);
return true;
}
#endif
#endif /* end of WASM_ENABLE_LLVM_LEGACY_PM != 0 || LLVM_VERSION_MAJOR < 12 */
/* Check whether the target supports hardware atomic instructions */
static bool
@ -2782,7 +2816,7 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
}
}
else {
#if WASM_ENABLE_LLVM_LEGACY_PM == 0
#if WASM_ENABLE_LLVM_LEGACY_PM == 0 && LLVM_VERSION_MAJOR >= 12
/* Run llvm new pass manager for AOT compiler if llvm
legacy pass manager isn't used */
bh_print_time("Begin to run llvm optimization passes");

View File

@ -371,11 +371,6 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
bool
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
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);
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -2103,8 +2103,10 @@ 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));
bh_assert(sizeof(obj_data->target_info.arch)
== sizeof(comp_ctx->target_arch));
bh_memcpy_s(obj_data->target_info.arch, sizeof(obj_data->target_info.arch),
comp_ctx->target_arch, sizeof(comp_ctx->target_arch));
return true;
}
@ -2180,6 +2182,8 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
|| !strcmp(section_name, ".rodata")
/* ".rodata.cst4/8/16/.." */
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
/* ".rodata.strn.m" */
|| !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
|| (!strcmp(section_name, ".rdata")
&& get_relocations_count(sec_itr, &relocation_count)
&& relocation_count > 0));
@ -2399,13 +2403,15 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
relocation->relocation_type = (uint32)type;
relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym);
/* for ".LCPIxxx", ".LJTIxxx" and ".LBBxxx" relocation,
* transform the symbol name to real section name and set
/* for ".LCPIxxx", ".LJTIxxx", ".LBBxxx" and switch lookup table
* relocation, transform the symbol name to real section name and set
* addend to the offset of the symbol in the real section */
if (relocation->symbol_name
&& (str_starts_with(relocation->symbol_name, ".LCPI")
|| str_starts_with(relocation->symbol_name, ".LJTI")
|| str_starts_with(relocation->symbol_name, ".LBB"))) {
|| str_starts_with(relocation->symbol_name, ".LBB")
|| str_starts_with(relocation->symbol_name,
".Lswitch.table."))) {
/* change relocation->relocation_addend and
relocation->symbol_name */
LLVMSectionIteratorRef contain_section;

View File

@ -141,7 +141,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
comp_ctx->comp_data->memories[0].num_bytes_per_page;
uint32 init_page_count =
comp_ctx->comp_data->memories[0].mem_init_page_count;
uint64 mem_data_size = num_bytes_per_page * init_page_count;
uint64 mem_data_size = (uint64)num_bytes_per_page * init_page_count;
if (mem_offset + bytes <= mem_data_size) {
/* inside memory space */

View File

@ -529,7 +529,6 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
default:
bh_assert(0);
return false;
;
}
}

View File

@ -2276,6 +2276,9 @@ aot_value_stack_destroy(AOTValueStack *stack)
wasm_runtime_free(value);
value = p;
}
stack->value_list_head = NULL;
stack->value_list_end = NULL;
}
void
@ -2319,6 +2322,9 @@ aot_block_stack_destroy(AOTBlockStack *stack)
aot_block_destroy(block);
block = p;
}
stack->block_list_head = NULL;
stack->block_list_end = NULL;
}
void

View File

@ -111,9 +111,15 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
for (auto &F : *Mod) {
auto Attrs = F.getAttributes();
StringRef Value = options.NoFramePointerElim ? "all" : "none";
#if LLVM_VERSION_MAJOR <= 13
Attrs =
Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
"frame-pointer", Value);
#else
Attrs = Attrs.addAttributeAtIndex(F.getContext(),
AttributeList::FunctionIndex,
"frame-pointer", Value);
#endif
F.setAttributes(Attrs);
}
}
@ -293,6 +299,8 @@ aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
#endif /* WASM_ENABLE_SIMD */
}
#if WASM_ENABLE_LAZY_JIT != 0
#if LLVM_VERSION_MAJOR < 12
LLVMOrcJITTargetMachineBuilderRef
LLVMOrcJITTargetMachineBuilderFromTargetMachine(LLVMTargetMachineRef TM);
@ -304,8 +312,6 @@ LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM)
}
#endif
#if WASM_ENABLE_LAZY_JIT != 0
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
void
@ -348,7 +354,7 @@ aot_lookup_orcjit_func(LLVMOrcLLJITRef orc_lazyjit, void *module_inst,
func_ptrs[func_idx] = (void *)func_addr;
return (void *)func_addr;
}
#endif
#endif /* end of WASM_ENABLE_LAZY_JIT != 0 */
void
aot_func_disable_tce(LLVMValueRef func)
@ -356,11 +362,18 @@ aot_func_disable_tce(LLVMValueRef func)
Function *F = unwrap<Function>(func);
auto Attrs = F->getAttributes();
#if LLVM_VERSION_MAJOR <= 13
Attrs = Attrs.addAttribute(F->getContext(), AttributeList::FunctionIndex,
"disable-tail-calls", "true");
#else
Attrs =
Attrs.addAttributeAtIndex(F->getContext(), AttributeList::FunctionIndex,
"disable-tail-calls", "true");
#endif
F->setAttributes(Attrs);
}
#if LLVM_VERSION_MAJOR >= 12
void
aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx)
{
@ -403,6 +416,7 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx)
ModulePassManager MPM;
#if LLVM_VERSION_MAJOR <= 13
PassBuilder::OptimizationLevel OL;
switch (comp_ctx->opt_level) {
@ -420,6 +434,25 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx)
OL = PassBuilder::OptimizationLevel::O3;
break;
}
#else
OptimizationLevel OL;
switch (comp_ctx->opt_level) {
case 0:
OL = OptimizationLevel::O0;
break;
case 1:
OL = OptimizationLevel::O1;
break;
case 2:
OL = OptimizationLevel::O2;
break;
case 3:
default:
OL = OptimizationLevel::O3;
break;
}
#endif /* end of LLVM_VERSION_MAJOR */
if (comp_ctx->disable_llvm_lto) {
disable_llvm_lto = true;
@ -478,3 +511,4 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx)
}
#endif
}
#endif /* end of LLVM_VERSION_MAJOR >= 12 */

View File

@ -1083,8 +1083,13 @@ jit_compile_func(JitCompContext *cc)
jit_set_last_error(cc, "allocate memory failed.");
goto fail;
}
#if WASM_ENABLE_FAST_INTERP != 0
for (i = 0; i <= br_count; i++)
read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]);
#else
for (i = 0; i <= br_count; i++)
br_depths[i] = *frame_ip++;
#endif
if (!jit_compile_op_br_table(cc, br_depths, br_count,
&frame_ip)) {
@ -1095,6 +1100,34 @@ jit_compile_func(JitCompContext *cc)
jit_free(br_depths);
break;
#if WASM_ENABLE_FAST_INTERP == 0
case EXT_OP_BR_TABLE_CACHE:
{
BrTableCache *node = bh_list_first_elem(
cc->cur_wasm_module->br_table_cache_list);
BrTableCache *node_next;
uint8 *p_opcode = frame_ip - 1;
read_leb_uint32(frame_ip, frame_ip_end, br_count);
while (node) {
node_next = bh_list_elem_next(node);
if (node->br_table_op_addr == p_opcode) {
br_depths = node->br_depths;
if (!jit_compile_op_br_table(cc, br_depths, br_count,
&frame_ip)) {
return false;
}
break;
}
node = node_next;
}
bh_assert(node);
break;
}
#endif
case WASM_OP_RETURN:
if (!jit_compile_op_return(cc, &frame_ip))
return false;

View File

@ -637,6 +637,12 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);
/**
* Allocate memory from the heap of WASM module instance
*
* Note: wasm_runtime_module_malloc can call heap functions inside
* the module instance and thus cause a memory growth.
* This API needs to be used very carefully when you have a native
* pointers to the module instance memory obtained with
* wasm_runtime_addr_app_to_native or similar APIs.
*
* @param module_inst the WASM module instance which contains heap
* @param size the size bytes to allocate
* @param p_native_addr return native address of the allocated memory
@ -699,6 +705,10 @@ wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst,
* space or memory space. Moreover, it checks whether it is the offset of a
* string that is end with '\0'.
*
* Note: The validation result, especially the NUL termination check,
* is not reliable for a module instance with multiple threads because
* other threads can modify the heap behind us.
*
* @param module_inst the WASM module instance
* @param app_str_offset the app address of the string to validate, which is a
* relative address
@ -729,6 +739,10 @@ wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
/**
* Convert app address(relative address) to native address(absolute address)
*
* Note that native addresses to module instance memory can be invalidated
* on a memory growth. (Except shared memory, whose native addresses are
* stable.)
*
* @param module_inst the WASM module instance
* @param app_offset the app adress
*

View File

@ -330,6 +330,14 @@ typedef struct StringNode {
char *str;
} StringNode, *StringList;
typedef struct BrTableCache {
struct BrTableCache *next;
/* Address of br_table opcode */
uint8 *br_table_op_addr;
uint32 br_count;
uint32 br_depths[1];
} BrTableCache;
#if WASM_ENABLE_DEBUG_INTERP != 0
typedef struct WASMFastOPCodeNode {
struct WASMFastOPCodeNode *next;
@ -415,6 +423,10 @@ struct WASMModule {
bool possible_memory_grow;
StringList const_str_list;
#if WASM_ENABLE_FAST_INTERP == 0
bh_list br_table_cache_list_head;
bh_list *br_table_cache_list;
#endif
#if WASM_ENABLE_LIBC_WASI != 0
WASIArguments wasi_args;

View File

@ -259,19 +259,21 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
--frame_csp; \
} while (0)
#define POP_CSP_N(n) \
do { \
uint32 *frame_sp_old = frame_sp; \
uint32 cell_num_to_copy; \
POP_CSP_CHECK_OVERFLOW(n + 1); \
frame_csp -= n; \
frame_ip = (frame_csp - 1)->target_addr; \
/* copy arity values of block */ \
frame_sp = (frame_csp - 1)->frame_sp; \
cell_num_to_copy = (frame_csp - 1)->cell_num; \
word_copy(frame_sp, frame_sp_old - cell_num_to_copy, \
cell_num_to_copy); \
frame_sp += cell_num_to_copy; \
#define POP_CSP_N(n) \
do { \
uint32 *frame_sp_old = frame_sp; \
uint32 cell_num_to_copy; \
POP_CSP_CHECK_OVERFLOW(n + 1); \
frame_csp -= n; \
frame_ip = (frame_csp - 1)->target_addr; \
/* copy arity values of block */ \
frame_sp = (frame_csp - 1)->frame_sp; \
cell_num_to_copy = (frame_csp - 1)->cell_num; \
if (cell_num_to_copy > 0) { \
word_copy(frame_sp, frame_sp_old - cell_num_to_copy, \
cell_num_to_copy); \
} \
frame_sp += cell_num_to_copy; \
} while (0)
/* Pop the given number of elements from the given frame's stack. */
@ -697,7 +699,7 @@ static inline int64
sign_ext_8_64(int8 val)
{
if (val & 0x80)
return (int64)val | (int64)0xffffffffffffff00;
return (int64)val | (int64)0xffffffffffffff00LL;
return val;
}
@ -705,7 +707,7 @@ static inline int64
sign_ext_16_64(int16 val)
{
if (val & 0x8000)
return (int64)val | (int64)0xffffffffffff0000;
return (int64)val | (int64)0xffffffffffff0000LL;
return val;
}
@ -713,15 +715,22 @@ static inline int64
sign_ext_32_64(int32 val)
{
if (val & (int32)0x80000000)
return (int64)val | (int64)0xffffffff00000000;
return (int64)val | (int64)0xffffffff00000000LL;
return val;
}
static inline void
word_copy(uint32 *dest, uint32 *src, unsigned num)
{
for (; num > 0; num--)
*dest++ = *src++;
bh_assert(dest != NULL);
bh_assert(src != NULL);
bh_assert(num > 0);
if (dest != src) {
/* No overlap buffer */
bh_assert(!((src < dest) && (dest < src + num)));
for (; num > 0; num--)
*dest++ = *src++;
}
}
static inline WASMInterpFrame *
@ -765,7 +774,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMFunctionImport *func_import = cur_func->u.func_import;
unsigned local_cell_num = 2;
WASMInterpFrame *frame;
uint32 argv_ret[2];
uint32 argv_ret[2], cur_func_index;
void *native_func_pointer = NULL;
char buf[128];
bool ret;
@ -780,7 +790,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
wasm_exec_env_set_cur_frame(exec_env, frame);
if (!func_import->func_ptr_linked) {
cur_func_index = (uint32)(cur_func - module_inst->functions);
bh_assert(cur_func_index < module_inst->module->import_function_count);
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
if (!native_func_pointer) {
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
func_import->module_name, func_import->field_name);
@ -790,9 +804,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (func_import->call_conv_wasm_c_api) {
ret = wasm_runtime_invoke_c_api_native(
(WASMModuleInstanceCommon *)module_inst,
func_import->func_ptr_linked, func_import->func_type,
cur_func->param_cell_num, frame->lp,
(WASMModuleInstanceCommon *)module_inst, native_func_pointer,
func_import->func_type, cur_func->param_cell_num, frame->lp,
func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) {
argv_ret[0] = frame->lp[0];
@ -801,13 +814,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
}
else if (!func_import->call_conv_raw) {
ret = wasm_runtime_invoke_native(
exec_env, func_import->func_ptr_linked, func_import->func_type,
exec_env, native_func_pointer, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
}
else {
ret = wasm_runtime_invoke_native_raw(
exec_env, func_import->func_ptr_linked, func_import->func_type,
exec_env, native_func_pointer, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
}
@ -1084,7 +1097,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
value_type = *frame_ip++;
param_cell_num = 0;
cell_num = wasm_value_type_cell_num(value_type);
cell_num = 0;
handle_op_loop:
PUSH_CSP(LABEL_TYPE_LOOP, param_cell_num, cell_num, frame_ip);
HANDLE_OP_END();
@ -1207,12 +1220,33 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
lidx = POP_I32();
if (lidx > count)
lidx = count;
for (i = 0; i < lidx; i++)
skip_leb(frame_ip);
read_leb_uint32(frame_ip, frame_ip_end, depth);
depth = frame_ip[lidx];
goto label_pop_csp_n;
}
HANDLE_OP(EXT_OP_BR_TABLE_CACHE)
{
BrTableCache *node =
bh_list_first_elem(module->module->br_table_cache_list);
BrTableCache *node_next;
#if WASM_ENABLE_THREAD_MGR != 0
CHECK_SUSPEND_FLAGS();
#endif
lidx = POP_I32();
while (node) {
node_next = bh_list_elem_next(node);
if (node->br_table_op_addr == frame_ip - 1) {
depth = node->br_depths[lidx];
goto label_pop_csp_n;
}
node = node_next;
}
bh_assert(0);
HANDLE_OP_END();
}
HANDLE_OP(WASM_OP_RETURN)
{
frame_sp -= cur_func->ret_cell_num;
@ -3594,7 +3628,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
call_func_from_return_call:
{
POP(cur_func->param_cell_num);
word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
if (cur_func->param_cell_num > 0) {
word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
}
FREE_FRAME(exec_env, frame);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
goto call_func_from_entry;
@ -3606,7 +3642,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env);
POP(cur_func->param_cell_num);
SYNC_ALL_TO_FRAME();
word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
if (cur_func->param_cell_num > 0) {
word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
}
prev_frame = frame;
}

View File

@ -764,7 +764,7 @@ static inline int64
sign_ext_8_64(int8 val)
{
if (val & 0x80)
return (int64)val | (int64)0xffffffffffffff00;
return (int64)val | (int64)0xffffffffffffff00LL;
return val;
}
@ -772,7 +772,7 @@ static inline int64
sign_ext_16_64(int16 val)
{
if (val & 0x8000)
return (int64)val | (int64)0xffffffffffff0000;
return (int64)val | (int64)0xffffffffffff0000LL;
return val;
}
@ -780,15 +780,22 @@ static inline int64
sign_ext_32_64(int32 val)
{
if (val & (int32)0x80000000)
return (int64)val | (int64)0xffffffff00000000;
return (int64)val | (int64)0xffffffff00000000LL;
return val;
}
static inline void
word_copy(uint32 *dest, uint32 *src, unsigned num)
{
for (; num > 0; num--)
*dest++ = *src++;
bh_assert(dest != NULL);
bh_assert(src != NULL);
bh_assert(num > 0);
if (dest != src) {
/* No overlap buffer */
bh_assert(!((src < dest) && (dest < src + num)));
for (; num > 0; num--)
*dest++ = *src++;
}
}
static inline WASMInterpFrame *
@ -832,7 +839,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMFunctionImport *func_import = cur_func->u.func_import;
unsigned local_cell_num = 2;
WASMInterpFrame *frame;
uint32 argv_ret[2];
uint32 argv_ret[2], cur_func_index;
void *native_func_pointer = NULL;
bool ret;
if (!(frame = ALLOC_FRAME(exec_env,
@ -846,7 +854,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
wasm_exec_env_set_cur_frame(exec_env, frame);
if (!func_import->func_ptr_linked) {
cur_func_index = (uint32)(cur_func - module_inst->functions);
bh_assert(cur_func_index < module_inst->module->import_function_count);
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
if (!native_func_pointer) {
char buf[128];
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
@ -857,9 +869,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (func_import->call_conv_wasm_c_api) {
ret = wasm_runtime_invoke_c_api_native(
(WASMModuleInstanceCommon *)module_inst,
func_import->func_ptr_linked, func_import->func_type,
cur_func->param_cell_num, frame->lp,
(WASMModuleInstanceCommon *)module_inst, native_func_pointer,
func_import->func_type, cur_func->param_cell_num, frame->lp,
func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) {
argv_ret[0] = frame->lp[0];
@ -868,13 +879,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
}
else if (!func_import->call_conv_raw) {
ret = wasm_runtime_invoke_native(
exec_env, func_import->func_ptr_linked, func_import->func_type,
exec_env, native_func_pointer, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
}
else {
ret = wasm_runtime_invoke_native_raw(
exec_env, func_import->func_ptr_linked, func_import->func_type,
exec_env, native_func_pointer, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
}
@ -3532,6 +3543,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(EXT_OP_BLOCK)
HANDLE_OP(EXT_OP_LOOP)
HANDLE_OP(EXT_OP_IF)
HANDLE_OP(EXT_OP_BR_TABLE_CACHE)
{
wasm_set_exception(module, "unsupported opcode");
goto got_exception;
@ -3571,7 +3583,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
}
frame->lp = frame->operand + cur_func->const_cell_num;
word_copy(frame->lp, lp_base, lp - lp_base);
if (lp - lp_base > 0) {
word_copy(frame->lp, lp_base, lp - lp_base);
}
wasm_runtime_free(lp_base);
FREE_FRAME(exec_env, frame);
frame_ip += cur_func->param_count * sizeof(int16);
@ -3598,6 +3612,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
outs_area->lp = outs_area->operand + cur_func->const_cell_num;
}
if ((uint8 *)(outs_area->lp + cur_func->param_cell_num)
> exec_env->wasm_stack.s.top_boundary) {
wasm_set_exception(module, "wasm operand stack overflow");
goto got_exception;
}
for (i = 0; i < cur_func->param_count; i++) {
if (cur_func->param_types[i] == VALUE_TYPE_I64
|| cur_func->param_types[i] == VALUE_TYPE_F64) {
@ -3684,8 +3705,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame->operand + cur_wasm_func->const_cell_num;
/* Initialize the consts */
word_copy(frame->operand, (uint32 *)cur_wasm_func->consts,
cur_wasm_func->const_cell_num);
if (cur_wasm_func->const_cell_num > 0) {
word_copy(frame->operand, (uint32 *)cur_wasm_func->consts,
cur_wasm_func->const_cell_num);
}
/* Initialize the local variables */
memset(frame_lp + cur_func->param_cell_num, 0,
@ -3786,6 +3809,13 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
frame->lp = frame->operand + 0;
frame->ret_offset = 0;
if ((uint8 *)(outs_area->operand + function->const_cell_num + argc)
> exec_env->wasm_stack.s.top_boundary) {
wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
"wasm operand stack overflow");
return;
}
if (argc > 0)
word_copy(outs_area->operand + function->const_cell_num, argv, argc);

View File

@ -10,6 +10,7 @@
#include "wasm_opcode.h"
#include "wasm_runtime.h"
#include "../common/wasm_native.h"
#include "../common/wasm_memory.h"
#if WASM_ENABLE_DEBUG_INTERP != 0
#include "../libraries/debug-engine/debug_engine.h"
#endif
@ -1233,9 +1234,6 @@ fail:
return false;
}
unsigned
wasm_runtime_memory_pool_size();
static bool
check_memory_init_size(uint32 init_size, char *error_buf, uint32 error_buf_size)
{
@ -3285,6 +3283,9 @@ create_module(char *error_buf, uint32 error_buf_size)
{
WASMModule *module =
loader_malloc(sizeof(WASMModule), error_buf, error_buf_size);
#if WASM_ENABLE_FAST_INTERP == 0
bh_list_status ret;
#endif
if (!module) {
return NULL;
@ -3295,6 +3296,13 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */
module->start_function = (uint32)-1;
#if WASM_ENABLE_FAST_INTERP == 0
module->br_table_cache_list = &module->br_table_cache_list_head;
ret = bh_list_init(module->br_table_cache_list);
bh_assert(ret == BH_LIST_SUCCESS);
(void)ret;
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
module->import_module_list = &module->import_module_list_head;
#endif
@ -3309,16 +3317,18 @@ create_module(char *error_buf, uint32 error_buf_size)
}
#if WASM_ENABLE_DEBUG_INTERP != 0
static void
record_fast_op(WASMModule *module, uint8 *pos, uint8 orig_op)
static bool
record_fast_op(WASMModule *module, uint8 *pos, uint8 orig_op, char *error_buf,
uint32 error_buf_size)
{
WASMFastOPCodeNode *fast_op =
loader_malloc(sizeof(WASMFastOPCodeNode), NULL, 0);
loader_malloc(sizeof(WASMFastOPCodeNode), error_buf, error_buf_size);
if (fast_op) {
fast_op->offset = pos - module->load_addr;
fast_op->orig_op = orig_op;
bh_list_insert(&module->fast_opcode_list, fast_op);
}
return fast_op ? true : false;
}
#endif
@ -3735,6 +3745,18 @@ wasm_loader_unload(WASMModule *module)
}
}
#if WASM_ENABLE_FAST_INTERP == 0
if (module->br_table_cache_list) {
BrTableCache *node = bh_list_first_elem(module->br_table_cache_list);
BrTableCache *node_next;
while (node) {
node_next = bh_list_elem_next(node);
wasm_runtime_free(node);
node = node_next;
}
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
/* just release the sub module list */
if (module->import_module_list) {
@ -3906,10 +3928,24 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
case WASM_OP_BR_TABLE:
read_leb_uint32(p, p_end, count); /* lable num */
for (i = 0; i <= count; i++) /* lableidxs */
#if WASM_ENABLE_FAST_INTERP != 0
for (i = 0; i <= count; i++) /* lableidxs */
skip_leb_uint32(p, p_end);
#else
p += count + 1;
while (*p == WASM_OP_NOP)
p++;
#endif
break;
#if WASM_ENABLE_FAST_INTERP == 0
case EXT_OP_BR_TABLE_CACHE:
read_leb_uint32(p, p_end, count); /* lable num */
while (*p == WASM_OP_NOP)
p++;
break;
#endif
case WASM_OP_RETURN:
break;
@ -5028,8 +5064,8 @@ wasm_loader_emit_const(WASMLoaderContext *ctx, void *value, bool is_32_bit)
bh_assert(((uintptr_t)ctx->p_code_compiled & 1) == 0);
#endif
bh_memcpy_s(ctx->p_code_compiled,
ctx->p_code_compiled_end - ctx->p_code_compiled, value,
size);
(uint32)(ctx->p_code_compiled_end - ctx->p_code_compiled),
value, size);
ctx->p_code_compiled += size;
}
else {
@ -6581,7 +6617,10 @@ re_scan:
* the block quickly.
*/
#if WASM_ENABLE_DEBUG_INTERP != 0
record_fast_op(module, p_org, *p_org);
if (!record_fast_op(module, p_org, *p_org, error_buf,
error_buf_size)) {
goto fail;
}
#endif
*p_org = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
#endif
@ -6830,6 +6869,13 @@ re_scan:
{
uint8 *ret_types = NULL;
uint32 ret_count = 0;
#if WASM_ENABLE_FAST_INTERP == 0
uint8 *p_depth_begin, *p_depth;
uint32 depth, j;
BrTableCache *br_table_cache = NULL;
p_org = p - 1;
#endif
read_leb_uint32(p, p_end, count);
#if WASM_ENABLE_FAST_INTERP != 0
@ -6837,6 +6883,9 @@ re_scan:
#endif
POP_I32();
#if WASM_ENABLE_FAST_INTERP == 0
p_depth_begin = p_depth = p;
#endif
for (i = 0; i <= count; i++) {
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end,
@ -6870,8 +6919,57 @@ re_scan:
goto fail;
}
}
#if WASM_ENABLE_FAST_INTERP == 0
depth = (uint32)(loader_ctx->frame_csp - 1 - frame_csp_tmp);
if (br_table_cache) {
br_table_cache->br_depths[i] = depth;
}
else {
if (depth > 255) {
/* The depth cannot be stored in one byte,
create br_table cache to store each depth */
#if WASM_ENABLE_DEBUG_INTERP != 0
if (!record_fast_op(module, p_org, *p_org,
error_buf, error_buf_size)) {
goto fail;
}
#endif
if (!(br_table_cache = loader_malloc(
offsetof(BrTableCache, br_depths)
+ sizeof(uint32)
* (uint64)(count + 1),
error_buf, error_buf_size))) {
goto fail;
}
*p_org = EXT_OP_BR_TABLE_CACHE;
br_table_cache->br_table_op_addr = p_org;
br_table_cache->br_count = count;
/* Copy previous depths which are one byte */
for (j = 0; j < i; j++) {
br_table_cache->br_depths[j] = p_depth_begin[j];
}
br_table_cache->br_depths[i] = depth;
bh_list_insert(module->br_table_cache_list,
br_table_cache);
}
else {
/* The depth can be stored in one byte, use the
byte of the leb to store it */
*p_depth++ = (uint8)depth;
}
}
#endif
}
#if WASM_ENABLE_FAST_INTERP == 0
/* Set the tailing bytes to nop */
if (br_table_cache)
p_depth = p_depth_begin;
while (p_depth < p)
*p_depth++ = WASM_OP_NOP;
#endif
RESET_STACK();
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
break;
@ -7615,7 +7713,10 @@ re_scan:
if (global_type == VALUE_TYPE_I64
|| global_type == VALUE_TYPE_F64) {
#if WASM_ENABLE_DEBUG_INTERP != 0
record_fast_op(module, p_org, *p_org);
if (!record_fast_op(module, p_org, *p_org, error_buf,
error_buf_size)) {
goto fail;
}
#endif
*p_org = WASM_OP_GET_GLOBAL_64;
}
@ -7669,14 +7770,20 @@ re_scan:
if (global_type == VALUE_TYPE_I64
|| global_type == VALUE_TYPE_F64) {
#if WASM_ENABLE_DEBUG_INTERP != 0
record_fast_op(module, p_org, *p_org);
if (!record_fast_op(module, p_org, *p_org, error_buf,
error_buf_size)) {
goto fail;
}
#endif
*p_org = WASM_OP_SET_GLOBAL_64;
}
else if (module->aux_stack_size > 0
&& global_idx == module->aux_stack_top_global_index) {
#if WASM_ENABLE_DEBUG_INTERP != 0
record_fast_op(module, p_org, *p_org);
if (!record_fast_op(module, p_org, *p_org, error_buf,
error_buf_size)) {
goto fail;
}
#endif
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
}

View File

@ -10,6 +10,7 @@
#include "wasm_opcode.h"
#include "wasm_runtime.h"
#include "../common/wasm_native.h"
#include "../common/wasm_memory.h"
#if WASM_ENABLE_FAST_JIT != 0
#include "../fast-jit/jit_compiler.h"
#include "../fast-jit/jit_codecache.h"
@ -501,9 +502,6 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
return true;
}
unsigned
wasm_runtime_memory_pool_size();
static bool
load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
WASMModule *parent_module, const char *sub_module_name,
@ -2167,6 +2165,9 @@ create_module(char *error_buf, uint32 error_buf_size)
{
WASMModule *module =
loader_malloc(sizeof(WASMModule), error_buf, error_buf_size);
#if WASM_ENABLE_FAST_INTERP == 0
bh_list_status ret;
#endif
if (!module) {
return NULL;
@ -2177,6 +2178,13 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */
module->start_function = (uint32)-1;
#if WASM_ENABLE_FAST_INTERP == 0
module->br_table_cache_list = &module->br_table_cache_list_head;
ret = bh_list_init(module->br_table_cache_list);
bh_assert(ret == BH_LIST_SUCCESS);
(void)ret;
#endif
return module;
}
@ -2453,6 +2461,18 @@ wasm_loader_unload(WASMModule *module)
}
}
#if WASM_ENABLE_FAST_INTERP == 0
if (module->br_table_cache_list) {
BrTableCache *node = bh_list_first_elem(module->br_table_cache_list);
BrTableCache *node_next;
while (node) {
node_next = bh_list_elem_next(node);
wasm_runtime_free(node);
node = node_next;
}
}
#endif
#if WASM_ENABLE_FAST_JIT != 0
if (module->fast_jit_func_ptrs) {
for (i = 0; i < module->function_count; i++) {
@ -2588,10 +2608,24 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
case WASM_OP_BR_TABLE:
read_leb_uint32(p, p_end, count); /* lable num */
for (i = 0; i <= count; i++) /* lableidxs */
#if WASM_ENABLE_FAST_INTERP != 0
for (i = 0; i <= count; i++) /* lableidxs */
skip_leb_uint32(p, p_end);
#else
p += count + 1;
while (*p == WASM_OP_NOP)
p++;
#endif
break;
#if WASM_ENABLE_FAST_INTERP == 0
case EXT_OP_BR_TABLE_CACHE:
read_leb_uint32(p, p_end, count); /* lable num */
while (*p == WASM_OP_NOP)
p++;
break;
#endif
case WASM_OP_RETURN:
break;
@ -3532,8 +3566,8 @@ wasm_loader_emit_const(WASMLoaderContext *ctx, void *value, bool is_32_bit)
bh_assert(((uintptr_t)ctx->p_code_compiled & 1) == 0);
#endif
bh_memcpy_s(ctx->p_code_compiled,
ctx->p_code_compiled_end - ctx->p_code_compiled, value,
size);
(uint32)(ctx->p_code_compiled_end - ctx->p_code_compiled),
value, size);
ctx->p_code_compiled += size;
}
else {
@ -5180,6 +5214,13 @@ re_scan:
{
uint8 *ret_types = NULL;
uint32 ret_count = 0;
#if WASM_ENABLE_FAST_INTERP == 0
uint8 *p_depth_begin, *p_depth;
uint32 depth, j;
BrTableCache *br_table_cache = NULL;
p_org = p - 1;
#endif
read_leb_uint32(p, p_end, count);
#if WASM_ENABLE_FAST_INTERP != 0
@ -5187,13 +5228,65 @@ re_scan:
#endif
POP_I32();
#if WASM_ENABLE_FAST_INTERP == 0
p_depth_begin = p_depth = p;
#endif
for (i = 0; i <= count; i++) {
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end,
error_buf, error_buf_size)))
goto fail;
#if WASM_ENABLE_FAST_INTERP == 0
depth = (uint32)(loader_ctx->frame_csp - 1 - frame_csp_tmp);
if (br_table_cache) {
br_table_cache->br_depths[i] = depth;
}
else {
if (depth > 255) {
/* The depth cannot be stored in one byte,
create br_table cache to store each depth */
#if WASM_ENABLE_DEBUG_INTERP != 0
if (!record_fast_op(module, p_org, *p_org,
error_buf, error_buf_size)) {
goto fail;
}
#endif
if (!(br_table_cache = loader_malloc(
offsetof(BrTableCache, br_depths)
+ sizeof(uint32)
* (uint64)(count + 1),
error_buf, error_buf_size))) {
goto fail;
}
*p_org = EXT_OP_BR_TABLE_CACHE;
br_table_cache->br_table_op_addr = p_org;
br_table_cache->br_count = count;
/* Copy previous depths which are one byte */
for (j = 0; j < i; j++) {
br_table_cache->br_depths[j] = p_depth_begin[j];
}
br_table_cache->br_depths[i] = depth;
bh_list_insert(module->br_table_cache_list,
br_table_cache);
}
else {
/* The depth can be stored in one byte, use the
byte of the leb to store it */
*p_depth++ = (uint8)depth;
}
}
#endif
}
#if WASM_ENABLE_FAST_INTERP == 0
/* Set the tailing bytes to nop */
if (br_table_cache)
p_depth = p_depth_begin;
while (p_depth < p)
*p_depth++ = WASM_OP_NOP;
#endif
RESET_STACK();
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);

View File

@ -263,12 +263,13 @@ typedef enum WASMOpcode {
WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */
WASM_OP_REF_FUNC = 0xd2, /* ref.func */
EXT_OP_BLOCK = 0xd3, /* block with blocktype */
EXT_OP_LOOP = 0xd4, /* loop with blocktype */
EXT_OP_IF = 0xd5, /* if with blocktype */
EXT_OP_BLOCK = 0xd3, /* block with blocktype */
EXT_OP_LOOP = 0xd4, /* loop with blocktype */
EXT_OP_IF = 0xd5, /* if with blocktype */
EXT_OP_BR_TABLE_CACHE = 0xd6, /* br_table from cache */
#if WASM_ENABLE_DEBUG_INTERP != 0
DEBUG_OP_BREAK = 0xd6, /* debug break point */
DEBUG_OP_BREAK = 0xd7, /* debug break point */
#endif
/* Post-MVP extend op prefix */
@ -675,7 +676,7 @@ typedef enum WASMAtomicEXTOpcode {
#if WASM_ENABLE_DEBUG_INTERP != 0
#define DEF_DEBUG_BREAK_HANDLE(_name) \
_name[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK); /* 0xd6 */
_name[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK); /* 0xd7 */
#else
#define DEF_DEBUG_BREAK_HANDLE(_name)
#endif
@ -901,6 +902,7 @@ typedef enum WASMAtomicEXTOpcode {
HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xd3 */ \
HANDLE_OPCODE(EXT_OP_LOOP), /* 0xd4 */ \
HANDLE_OPCODE(EXT_OP_IF), /* 0xd5 */ \
HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xd6 */ \
}; \
do { \
_name[WASM_OP_MISC_PREFIX] = \

View File

@ -222,6 +222,8 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
/* Adjust __heap_base global value */
global_idx = module->aux_heap_base_global_index;
bh_assert(module_inst->globals
&& global_idx < module_inst->global_count);
global_addr = module_inst->global_data
+ module_inst->globals[global_idx].data_offset;
*(uint32 *)global_addr = aux_heap_base;
@ -421,19 +423,6 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
}
}
if (mem_index == 0) {
/**
* no import memory and define memory, but still need heap
* for wasm code
*/
if (!(memory = memories[mem_index++] =
memory_instantiate(module_inst, 0, 0, 0, heap_size, 0,
error_buf, error_buf_size))) {
memories_deinstantiate(module_inst, memories, memory_count);
return NULL;
}
}
bh_assert(mem_index == memory_count);
(void)module_inst;
return memories;
@ -598,6 +587,14 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
return NULL;
}
total_size = sizeof(void *) * (uint64)module->import_function_count;
if (total_size > 0
&& !(module_inst->import_func_ptrs =
runtime_malloc(total_size, error_buf, error_buf_size))) {
wasm_runtime_free(functions);
return NULL;
}
/* instantiate functions from import section */
function = functions;
import = module->import_functions;
@ -626,6 +623,10 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
function->local_count = 0;
function->local_types = NULL;
/* Copy the function pointer to current instance */
module_inst->import_func_ptrs[i] =
function->u.func_import->func_ptr_linked;
function++;
}
@ -1117,18 +1118,12 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf,
&& !func->import_func_linked
#endif
) {
#if WASM_ENABLE_SPEC_TEST != 0
set_error_buf(error_buf, error_buf_size,
"unknown import or incompatible import type");
return false;
#else
#if WASM_ENABLE_WAMR_COMPILER == 0
LOG_WARNING("warning: failed to link import function (%s, %s)",
func->module_name, func->field_name);
#else
/* do nothing to avoid confused message */
#endif /* WASM_ENABLE_WAMR_COMPILER == 0 */
#endif /* WASM_ENABLE_SPEC_TEST != 0 */
}
}
@ -1357,12 +1352,14 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
goto fail;
}
data_seg->base_offset.u.i32 =
base_offset =
globals[data_seg->base_offset.u.global_index].initial_value.i32;
}
else {
base_offset = (uint32)data_seg->base_offset.u.i32;
}
/* check offset */
base_offset = (uint32)data_seg->base_offset.u.i32;
if (base_offset > memory_size) {
LOG_DEBUG("base_offset(%d) > memory_size(%d)", base_offset,
memory_size);
@ -1619,6 +1616,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
memories_deinstantiate(module_inst, module_inst->memories,
module_inst->memory_count);
if (module_inst->import_func_ptrs) {
wasm_runtime_free(module_inst->import_func_ptrs);
}
tables_deinstantiate(module_inst->tables, module_inst->table_count);
functions_deinstantiate(module_inst->functions,
module_inst->function_count);

View File

@ -181,6 +181,9 @@ struct WASMModuleInstance {
uint32 export_tab_count;
#endif
/* Array of function pointers to import functions */
void **import_func_ptrs;
WASMMemoryInstance **memories;
WASMTableInstance **tables;
WASMGlobalInstance *globals;

View File

@ -471,7 +471,7 @@ handle_threadstop_request(WASMGDBServer *server, char *payload)
void
handle_set_current_thread(WASMGDBServer *server, char *payload)
{
LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload, payload);
LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
if ('g' == *payload++) {
uint64 tid = strtoll(payload, NULL, 16);
if (tid > 0)

View File

@ -154,8 +154,8 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
// Prepare input parameters.
__wasi_iovec_t *ri_data = NULL;
size_t i = 0;
size_t ro_datalen;
__wasi_roflags_t ro_flags;
size_t ro_datalen = 0;
__wasi_roflags_t ro_flags = 0;
if (NULL == msg) {
HANDLE_ERROR(__WASI_ERRNO_INVAL)

View File

@ -81,10 +81,11 @@ typedef char *_va_list;
int32 n; \
\
/* additional 2 bytes: one is the format char, \
* the other is `\0` */ \
if (fmt - fmt_start_addr + 2 >= fmt_buf_len) { \
bh_assert(fmt - fmt_start_addr <= UINT32_MAX - 2); \
fmt_buf_len = fmt - fmt_start_addr + 2; \
the other is `\0` */ \
if ((uint32)(fmt - fmt_start_addr + 2) >= fmt_buf_len) { \
bh_assert((uint32)(fmt - fmt_start_addr) <= \
UINT32_MAX - 2); \
fmt_buf_len = (uint32)(fmt - fmt_start_addr + 2); \
if (!(fmt_buf = wasm_runtime_malloc(fmt_buf_len))) { \
print_err(out, ctx); \
break; \
@ -92,8 +93,8 @@ typedef char *_va_list;
} \
\
memset(fmt_buf, 0, fmt_buf_len); \
bh_memcpy_s(fmt_buf, fmt_buf_len, \
fmt_start_addr, fmt - fmt_start_addr + 1);
bh_memcpy_s(fmt_buf, fmt_buf_len, fmt_start_addr, \
(uint32)(fmt - fmt_start_addr + 1));
/* clang-format on */
#define OUTPUT_TEMP_FORMAT() \
@ -125,7 +126,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
int long_ctr = 0;
uint8 *native_end_addr;
const char *fmt_start_addr = NULL;
bool is_signed;
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)ap, NULL,
&native_end_addr))
@ -142,7 +142,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
might_format = 1;
long_ctr = 0;
fmt_start_addr = fmt;
is_signed = false;
}
}
else {
@ -162,7 +161,11 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
case '7':
case '8':
case '9':
goto still_might_format;
case 't': /* ptrdiff_t */
case 'z': /* size_t (32bit on wasm) */
long_ctr = 1;
goto still_might_format;
case 'j':
@ -173,7 +176,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
case 'l':
long_ctr++;
/* Fall through */
case 'z':
case 'h':
/* FIXME: do nothing for these modifiers */
goto still_might_format;
@ -181,8 +183,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
case 'o':
case 'd':
case 'i':
is_signed = true;
/* Fall through */
case 'u':
case 'p':
case 'x':
@ -193,34 +193,34 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
PREPARE_TEMP_FORMAT();
if (long_ctr < 2) {
CHECK_VA_ARG(ap, uint32);
int32 d;
if (is_signed) {
int32 d;
d = _va_arg(ap, int32);
n = snprintf(buf, sizeof(buf), fmt_buf, d);
}
else {
uint32 u;
u = _va_arg(ap, uint32);
n = snprintf(buf, sizeof(buf), fmt_buf, u);
CHECK_VA_ARG(ap, uint32);
d = _va_arg(ap, int32);
if (long_ctr == 1) {
uint32 fmt_end_idx = (uint32)(fmt - fmt_start_addr);
if (fmt_buf[fmt_end_idx - 1] == 'l'
|| fmt_buf[fmt_end_idx - 1] == 'z'
|| fmt_buf[fmt_end_idx - 1] == 't') {
/* The %ld, %zd and %td should be treated as
* 32bit integer in wasm */
fmt_buf[fmt_end_idx - 1] = fmt_buf[fmt_end_idx];
fmt_buf[fmt_end_idx] = '\0';
}
}
n = snprintf(buf, sizeof(buf), fmt_buf, d);
}
else {
int64 lld;
/* Make 8-byte aligned */
ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7);
CHECK_VA_ARG(ap, uint64);
if (is_signed) {
int64 lld;
lld = _va_arg(ap, int64);
n = snprintf(buf, sizeof(buf), fmt_buf, lld);
}
else {
uint64 llu;
llu = _va_arg(ap, uint64);
n = snprintf(buf, sizeof(buf), fmt_buf, llu);
}
lld = _va_arg(ap, int64);
n = snprintf(buf, sizeof(buf), fmt_buf, lld);
}
OUTPUT_TEMP_FORMAT();
@ -247,7 +247,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
s = start = addr_app_to_native(s_offset);
str_len = strlen(start);
str_len = (uint32)strlen(start);
if (str_len >= UINT32_MAX - 64) {
print_err(out, ctx);
if (fmt_buf != temp_fmt) {
@ -1067,6 +1067,9 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(printf, "($*)i"),
REG_NATIVE_FUNC(sprintf, "($$*)i"),
REG_NATIVE_FUNC(snprintf, "(*~$*)i"),
{ "vprintf", printf_wrapper, "($*)i", NULL },
{ "vsprintf", sprintf_wrapper, "($$*)i", NULL },
{ "vsnprintf", snprintf_wrapper, "(*~$*)i", NULL },
REG_NATIVE_FUNC(puts, "($)i"),
REG_NATIVE_FUNC(putchar, "(i)i"),
REG_NATIVE_FUNC(memcmp, "(**~)i"),

View File

@ -1185,10 +1185,19 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
uint64 total_size;
uint32 i;
iovec_app_t *ri_data_orig = ri_data;
uint8 *buf = NULL;
uint8 *buf_begin = NULL;
wasi_errno_t err;
size_t recv_bytes = 0;
if (!wasi_ctx)
if (!wasi_ctx) {
return __WASI_EINVAL;
}
if (ri_data_len == 0) {
return __WASI_EINVAL;
}
total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
if (!validate_native_addr(ro_data_len, (uint32)sizeof(uint32))
@ -1197,27 +1206,49 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
|| !validate_native_addr(ri_data, (uint32)total_size))
return __WASI_EINVAL;
/* recv ri_data one by one */
/* receive and scatter*/
for (total_size = 0, i = 0; i < ri_data_len; i++, ri_data++) {
total_size += ri_data->buf_len;
}
if (total_size >= UINT32_MAX
|| !(buf_begin = wasm_runtime_malloc((uint32)total_size))) {
return __WASI_ENOMEM;
}
memset(buf_begin, 0, total_size);
*ro_data_len = 0;
err = wasmtime_ssp_sock_recv(curfds, sock, buf_begin, total_size,
&recv_bytes);
if (err != __WASI_ESUCCESS) {
goto fail;
}
*ro_data_len = (uint32)recv_bytes;
buf = buf_begin;
ri_data = ri_data_orig;
for (i = 0; i < ri_data_len; ri_data++, i++) {
void *buf;
size_t bytes_recv;
char *native_addr;
if ((uint32)(buf - buf_begin) >= *ro_data_len) {
break;
}
if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
return __WASI_EINVAL;
err = __WASI_EINVAL;
goto fail;
}
buf = (void *)addr_app_to_native(ri_data->buf_offset);
err = wasmtime_ssp_sock_recv(curfds, sock, buf, ri_data->buf_len,
&bytes_recv);
if (err != __WASI_ESUCCESS) {
return err;
}
*ro_data_len += bytes_recv;
native_addr = (void *)addr_app_to_native(ri_data->buf_offset);
bh_memcpy_s(native_addr, ri_data->buf_len, buf, ri_data->buf_len);
buf += ri_data->buf_len;
}
*ro_flags = ri_flags;
return __WASI_ESUCCESS;
fail:
if (buf_begin) {
wasm_runtime_free(buf_begin);
}
return err;
}
static wasi_errno_t
@ -1232,12 +1263,21 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
uint64 total_size;
uint64 total_size = 0;
uint32 i;
const iovec_app_t *si_data_orig = si_data;
uint8 *buf = NULL;
uint8 *buf_begin = NULL;
wasi_errno_t err;
size_t send_bytes = 0;
if (!wasi_ctx)
if (!wasi_ctx) {
return __WASI_EINVAL;
}
if (si_data_len == 0) {
return __WASI_EINVAL;
}
total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
if (!validate_native_addr(so_data_len, sizeof(uint32))
@ -1245,26 +1285,40 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
|| !validate_native_addr((void *)si_data, (uint32)total_size))
return __WASI_EINVAL;
/* send si_data one by one */
*so_data_len = 0;
for (i = 0; i < si_data_len; i++, si_data++) {
void *buf;
size_t bytes_sent;
if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
return __WASI_EINVAL;
}
buf = (void *)addr_app_to_native(si_data->buf_offset);
err = wasmtime_ssp_sock_send(curfds, sock, buf, si_data->buf_len,
&bytes_sent);
if (err != __WASI_ESUCCESS) {
return err;
}
*so_data_len += bytes_sent;
/* gather and send */
for (total_size = 0, i = 0; i < si_data_len; i++, si_data++) {
total_size += si_data->buf_len;
}
if (total_size >= UINT32_MAX
|| !(buf_begin = wasm_runtime_malloc((uint32)total_size))) {
return __WASI_ENOMEM;
}
return __WASI_ESUCCESS;
buf = buf_begin;
si_data = si_data_orig;
for (i = 0; i < si_data_len; i++, si_data++) {
char *native_addr;
if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
err = __WASI_EINVAL;
goto fail;
}
native_addr = (char *)addr_app_to_native(si_data->buf_offset);
bh_memcpy_s(buf, si_data->buf_len, native_addr, si_data->buf_len);
buf += si_data->buf_len;
}
*so_data_len = 0;
err = wasmtime_ssp_sock_send(curfds, sock, buf_begin, total_size,
&send_bytes);
*so_data_len = (uint32)send_bytes;
fail:
if (buf_begin) {
wasm_runtime_free(buf_begin);
}
return err;
}
static wasi_errno_t

View File

@ -181,15 +181,19 @@ convert_clockid(__wasi_clockid_t in, clockid_t *out)
case __WASI_CLOCK_MONOTONIC:
*out = CLOCK_MONOTONIC;
return true;
#if defined(CLOCK_PROCESS_CPUTIME_ID)
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
*out = CLOCK_PROCESS_CPUTIME_ID;
return true;
#endif
case __WASI_CLOCK_REALTIME:
*out = CLOCK_REALTIME;
return true;
#if defined(CLOCK_THREAD_CPUTIME_ID)
case __WASI_CLOCK_THREAD_CPUTIME_ID:
*out = CLOCK_THREAD_CPUTIME_ID;
return true;
#endif
default:
return false;
}
@ -652,12 +656,13 @@ fd_table_insert_fd(struct fd_table *ft, int in, __wasi_filetype_t type,
REQUIRES_UNLOCKED(ft->lock)
{
struct fd_object *fo;
__wasi_errno_t error = fd_object_new(type, &fo);
__wasi_errno_t error = fd_object_new(type, &fo);
if (error != 0) {
close(in);
return error;
}
fo->number = in;
if (type == __WASI_FILETYPE_DIRECTORY) {
if (!mutex_init(&fo->directory.lock)) {
@ -877,7 +882,7 @@ wasmtime_ssp_fd_pread(
// Copy data back to vectors.
size_t bufoff = 0;
for (size_t i = 0; i < iovcnt; ++i) {
if (bufoff + iov[i].buf_len < len) {
if (bufoff + iov[i].buf_len < (size_t)len) {
bh_memcpy_s(iov[i].buf, iov[i].buf_len, buf + bufoff,
iov[i].buf_len);
bufoff += iov[i].buf_len;
@ -1356,8 +1361,9 @@ wasmtime_ssp_fd_allocate(
// conditions. We may end up shrinking the file right now.
struct stat sb;
int ret = fstat(fd_number(fo), &sb);
if (ret == 0 && sb.st_size < offset + len)
ret = ftruncate(fd_number(fo), offset + len);
off_t newsize = (off_t)(offset + len);
if (ret == 0 && sb.st_size < newsize)
ret = ftruncate(fd_number(fo), newsize);
#endif
fd_object_release(fo);
@ -1991,7 +1997,11 @@ wasmtime_ssp_fd_readdir(
size_t namlen = strlen(de->d_name);
__wasi_dirent_t cde = {
.d_next = fo->directory.offset,
#if CONFIG_HAS_D_INO
.d_ino = de->d_ino,
#else
.d_ino = 0,
#endif
.d_namlen = (uint32)namlen,
};
switch (de->d_type) {
@ -2682,11 +2692,84 @@ wasmtime_ssp_proc_raise(__wasi_signal_t sig)
{
static const int signals[] = {
#define X(v) [__WASI_##v] = v
X(SIGABRT), X(SIGALRM), X(SIGBUS), X(SIGCHLD), X(SIGCONT), X(SIGFPE),
X(SIGHUP), X(SIGILL), X(SIGINT), X(SIGKILL), X(SIGPIPE), X(SIGQUIT),
X(SIGSEGV), X(SIGSTOP), X(SIGSYS), X(SIGTERM), X(SIGTRAP), X(SIGTSTP),
X(SIGTTIN), X(SIGTTOU), X(SIGURG), X(SIGUSR1), X(SIGUSR2), X(SIGVTALRM),
X(SIGXCPU), X(SIGXFSZ),
#if defined(SIGABRT)
X(SIGABRT),
#endif
#if defined(SIGALRM)
X(SIGALRM),
#endif
#if defined(SIGBUS)
X(SIGBUS),
#endif
#if defined(SIGCHLD)
X(SIGCHLD),
#endif
#if defined(SIGCONT)
X(SIGCONT),
#endif
#if defined(SIGFPE)
X(SIGFPE),
#endif
#if defined(SIGHUP)
X(SIGHUP),
#endif
#if defined(SIGILL)
X(SIGILL),
#endif
#if defined(SIGINT)
X(SIGINT),
#endif
#if defined(SIGKILL)
X(SIGKILL),
#endif
#if defined(SIGPIPE)
X(SIGPIPE),
#endif
#if defined(SIGQUIT)
X(SIGQUIT),
#endif
#if defined(SIGSYS)
X(SIGSEGV),
#endif
#if defined(SIGSTOP)
X(SIGSTOP),
#endif
#if defined(SIGSYS)
X(SIGSYS),
#endif
#if defined(SIGTERM)
X(SIGTERM),
#endif
#if defined(SIGTRAP)
X(SIGTRAP),
#endif
#if defined(SIGTSTP)
X(SIGTSTP),
#endif
#if defined(SIGTTIN)
X(SIGTTIN),
#endif
#if defined(SIGTTOU)
X(SIGTTOU),
#endif
#if defined(SIGURG)
X(SIGURG),
#endif
#if defined(SIGUSR1)
X(SIGUSR1),
#endif
#if defined(SIGUSR2)
X(SIGUSR2),
#endif
#if defined(SIGVTALRM)
X(SIGVTALRM),
#endif
#if defined(SIGXCPU)
X(SIGXCPU),
#endif
#if defined(SIGXFSZ)
X(SIGXFSZ),
#endif
#undef X
};
if (sig >= sizeof(signals) / sizeof(signals[0]) || signals[sig] == 0)
@ -2726,33 +2809,42 @@ wasi_ssp_sock_accept(
__wasi_filetype_t wasi_type;
__wasi_rights_t max_base, max_inheriting;
struct fd_object *fo;
bh_socket_t new_sock;
bh_socket_t new_sock = -1;
int ret;
__wasi_errno_t error =
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ACCEPT, 0);
if (error != __WASI_ESUCCESS)
return error;
if (error != __WASI_ESUCCESS) {
goto fail;
}
ret = os_socket_accept(fd_number(fo), &new_sock, NULL, NULL);
fd_object_release(fo);
if (ret == BHT_ERROR)
return convert_errno(errno);
if (BHT_OK != ret) {
error = convert_errno(errno);
goto fail;
}
error = fd_determine_type_rights(new_sock, &wasi_type, &max_base,
&max_inheriting);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
goto fail;
}
error = fd_table_insert_fd(curfds, new_sock, wasi_type, max_base,
max_inheriting, fd_new);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
/* released in fd_table_insert_fd() */
new_sock = -1;
goto fail;
}
return __WASI_ESUCCESS;
fail:
if (-1 != new_sock) {
os_socket_close(new_sock);
}
return error;
}
__wasi_errno_t
@ -2816,7 +2908,7 @@ wasi_ssp_sock_bind(
ret = os_socket_bind(fd_number(fo), buf, &port);
fd_object_release(fo);
if (ret == BHT_ERROR) {
if (BHT_OK != ret) {
return convert_errno(errno);
}
@ -2849,7 +2941,7 @@ wasi_ssp_sock_connect(
ret = os_socket_connect(fd_number(fo), buf, addr->addr.ip4.port);
fd_object_release(fo);
if (ret == BHT_ERROR) {
if (BHT_OK != ret) {
return convert_errno(errno);
}
@ -2872,7 +2964,7 @@ wasi_ssp_sock_listen(
ret = os_socket_listen(fd_number(fo), backlog);
fd_object_release(fo);
if (ret == BHT_ERROR) {
if (BHT_OK != ret) {
return convert_errno(errno);
}
@ -2903,7 +2995,7 @@ wasi_ssp_sock_open(
tcp_or_udp = SOCKET_DGRAM == socktype ? 0 : 1;
ret = os_socket_create(&sock, tcp_or_udp);
if (ret == BHT_ERROR) {
if (BHT_OK != ret) {
return convert_errno(errno);
}
@ -2925,7 +3017,6 @@ wasi_ssp_sock_open(
error = fd_table_insert_fd(curfds, sock, wasi_type, max_base,
max_inheriting, sockfd);
if (error != __WASI_ESUCCESS) {
os_socket_close(sock);
return error;
}
@ -2950,7 +3041,7 @@ wasmtime_ssp_sock_recv(
ret = os_socket_recv(fd_number(fo), buf, buf_len);
fd_object_release(fo);
if (ret == BHT_ERROR) {
if (-1 == ret) {
return convert_errno(errno);
}
@ -2976,7 +3067,7 @@ wasmtime_ssp_sock_send(
ret = os_socket_send(fd_number(fo), buf, buf_len);
fd_object_release(fo);
if (ret == BHT_ERROR) {
if (-1 == ret) {
return convert_errno(errno);
}
@ -3001,7 +3092,7 @@ wasmtime_ssp_sock_shutdown(
ret = os_socket_shutdown(fd_number(fo));
fd_object_release(fo);
if (ret == BHT_ERROR)
if (BHT_OK != ret)
return convert_errno(errno);
return __WASI_ESUCCESS;

View File

@ -1,20 +0,0 @@
// 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
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef SIGNALS_H
#define SIGNALS_H
void
signals_init(void);
#endif

View File

@ -105,4 +105,10 @@
#define CONFIG_HAS_STD_ATOMIC 0
#endif
#if !defined(__NuttX__)
#define CONFIG_HAS_D_INO 1
#else
#define CONFIG_HAS_D_INO 0
#endif
#endif

View File

@ -681,8 +681,8 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
korp_tid handle;
os_mutex_lock(&cluster_list_lock);
if (!clusters_have_exec_env(exec_env)) {
/* Invalid thread or the thread has exited */
if (!clusters_have_exec_env(exec_env) || exec_env->thread_is_detached) {
/* Invalid thread, thread has exited or thread has been detached */
if (ret_val)
*ret_val = NULL;
os_mutex_unlock(&cluster_list_lock);
@ -710,6 +710,7 @@ wasm_cluster_detach_thread(WASMExecEnv *exec_env)
joining it, otherwise let the system resources for the
thread be released after joining */
ret = os_thread_detach(exec_env->handle);
exec_env->thread_is_detached = true;
}
os_mutex_unlock(&cluster_list_lock);
return ret;
@ -802,6 +803,32 @@ wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
(void *)exec_env);
}
static void
wait_for_thread_visitor(void *node, void *user_data)
{
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
if (curr_exec_env == exec_env)
return;
wasm_cluster_join_thread(curr_exec_env, NULL);
}
void
wams_cluster_wait_for_all(WASMCluster *cluster)
{
traverse_list(&cluster->exec_env_list, wait_for_thread_visitor, NULL);
}
void
wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
WASMExecEnv *exec_env)
{
traverse_list(&cluster->exec_env_list, wait_for_thread_visitor,
(void *)exec_env);
}
bool
wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *))
{

View File

@ -106,6 +106,13 @@ void
wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
WASMExecEnv *exec_env);
void
wams_cluster_wait_for_all(WASMCluster *cluster);
void
wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
WASMExecEnv *exec_env);
bool
wasm_cluster_add_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
@ -148,8 +155,6 @@ 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 *

View File

@ -172,6 +172,7 @@ os_socket_inet_network(const char *cp, uint32 *out)
if (!cp)
return BHT_ERROR;
*out = inet_network(cp);
/* Note: ntohl(INADDR_NONE) == INADDR_NONE */
*out = ntohl(inet_addr(cp));
return BHT_OK;
}
}

View File

@ -411,6 +411,9 @@ init_stack_guard_pages()
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
uint8 *stack_min_addr = os_thread_get_stack_boundary();
if (stack_min_addr == NULL)
return false;
/* Touch each stack page to ensure that it has been mapped: the OS
may lazily grow the stack mapping as a guard page is hit. */
(void)touch_pages(stack_min_addr, page_size);

View File

@ -65,6 +65,14 @@ BH_VPRINTF(const char *format, va_list ap);
#define NULL (void *)0
#endif
#if !defined(BH_HAS_DLFCN)
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE)
#define BH_HAS_DLFCN 1
#else
#define BH_HAS_DLFCN 0
#endif
#endif
#ifndef __cplusplus
#ifndef true

View File

@ -90,8 +90,8 @@ strcpy(char *dest, const char *src)
const unsigned char *s = src;
unsigned char *d = dest;
while ((*d++ = *s++))
;
while ((*d++ = *s++)) {
}
return dest;
}

View File

@ -41,6 +41,12 @@ typedef pthread_t korp_thread;
#define os_printf printf
#define os_vprintf vprintf
#if defined(CONFIG_LIBC_DLFCN)
#define BH_HAS_DLFCN 1
#else
#define BH_HAS_DLFCN 0
#endif
/* On NuttX, time_t is uint32_t */
#define BH_TIME_T_MAX 0xffffffff

View File

@ -22,6 +22,19 @@ bh_assert_internal(int v, const char *file_name, int line_number,
#define bh_assert(expr) (void)0
#endif /* end of BH_DEBUG */
#if !defined(__has_extension)
#define __has_extension(a) 0
#endif
#if __STDC_VERSION__ >= 201112L \
|| (defined(__GNUC__) && __GNUC__ * 0x100 + __GNUC_MINOR__ >= 0x406) \
|| __has_extension(c_static_assert)
#define bh_static_assert(expr) _Static_assert(expr, #expr)
#else
#define bh_static_assert(expr) /* nothing */
#endif
#ifdef __cplusplus
}
#endif

View File

@ -5,12 +5,6 @@
#include "bh_common.h"
#ifdef RSIZE_MAX
#undef RSIZE_MAX
#endif
#define RSIZE_MAX 0x7FFFFFFF
int
b_memcpy_s(void *s1, unsigned int s1max, const void *s2, unsigned int n)
{
@ -20,7 +14,7 @@ b_memcpy_s(void *s1, unsigned int s1max, const void *s2, unsigned int n)
return 0;
}
if (s1 == NULL || s1max > RSIZE_MAX) {
if (s1 == NULL) {
return -1;
}
if (s2 == NULL || n > s1max) {
@ -40,7 +34,7 @@ b_memmove_s(void *s1, unsigned int s1max, const void *s2, unsigned int n)
return 0;
}
if (s1 == NULL || s1max > RSIZE_MAX) {
if (s1 == NULL) {
return -1;
}
if (s2 == NULL || n > s1max) {
@ -54,8 +48,7 @@ b_memmove_s(void *s1, unsigned int s1max, const void *s2, unsigned int n)
int
b_strcat_s(char *s1, unsigned int s1max, const char *s2)
{
if (NULL == s1 || NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1)
|| s1max > RSIZE_MAX) {
if (NULL == s1 || NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1)) {
return -1;
}
@ -66,8 +59,7 @@ b_strcat_s(char *s1, unsigned int s1max, const char *s2)
int
b_strcpy_s(char *s1, unsigned int s1max, const char *s2)
{
if (NULL == s1 || NULL == s2 || s1max < (strlen(s2) + 1)
|| s1max > RSIZE_MAX) {
if (NULL == s1 || NULL == s2 || s1max < (strlen(s2) + 1)) {
return -1;
}

View File

@ -129,11 +129,19 @@ int main(int argc, char **argv)
}
```
## Build native lib into shared library and register it with `iwasm` application
Developer can also build the native library into a shared library and register it with iwasm application:
```bash
iwasm --native-lib=<lib file> <wasm file>
```
Refer to [native lib sample](../samples/native-lib) for more details.
## Buffer address conversion and boundary check
A WebAssembly sandbox ensures applications only access to its own memory with a private address space. When passing a pointer address from WASM to native, the address value must be converted to native address before the native function can access it. It is also the native world's responsibility to check the buffer length is not over its sandbox boundary.
A WebAssembly sandbox ensures applications only access to its own memory with a private address space. When passing a pointer address from WASM to native, the address value must be converted to native address before the native function can access it. It is also the native world's responsibility to check the buffer length is not over its sandbox boundary.

View File

@ -107,7 +107,7 @@ Below is the reference implementation of the pub application. It utilizes a time
``` C
/* Timer callback */
void timer_update(user_timer_t timer
void timer_update(user_timer_t timer)
{
attr_container_t *event;

View File

@ -1,5 +1,11 @@
# wasm-c-api introduction
wasm-c-api is an engine-agnostic API to embed a WASM engine.
In wasm-micro-runtime, it's provided by the header file `wasm_c_api.h`.
Its functionalities are overlapping with `wasm_export.h`, which is
a native API of wasm-micro-runtime. An embedder is supposed to pick
one of these APIs, rather than mixing both of them.
All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b
of [wasm-c-api](https://github.com/WebAssembly/wasm-c-api).

View File

@ -41,6 +41,9 @@ endif
WAMR_BUILD_PLATFORM := nuttx
CFLAGS += -DBH_MALLOC=wasm_runtime_malloc
CFLAGS += -DBH_FREE=wasm_runtime_free
ifeq ($(WAMR_BUILD_TARGET), X86_32)
CFLAGS += -DBUILD_TARGET_X86_32
INVOKE_NATIVE := invokeNative_ia32.s

View File

@ -13,6 +13,10 @@
#include "bh_read_file.h"
#include "wasm_export.h"
#if BH_HAS_DLFCN
#include <dlfcn.h>
#endif
static int app_argc;
static char **app_argv;
@ -39,13 +43,18 @@ print_help()
printf(" --dir=<dir> Grant wasi access to the given host directories\n");
printf(" to the program, for example:\n");
printf(" --dir=<dir1> --dir=<dir2>\n");
printf(" --addr-pool= Grant wasi access to the given network addresses in\n");
printf(" --addr-pool=<addrs> Grant wasi access to the given network addresses in\n");
printf(" CIRD notation to the program, seperated with ',',\n");
printf(" for example:\n");
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
#endif
#if BH_HAS_DLFCN
printf(" --native-lib=<lib> Register native libraries to the WASM module, which\n");
printf(" are shared object (.so) files, for example:\n");
printf(" --native-lib=test1.so --native-lib=test2.so\n");
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
printf(" --module-path= Indicate a module search path. default is current\n"
printf(" --module-path=<path> Indicate a module search path. default is current\n"
" directory('./')\n");
#endif
#if WASM_ENABLE_LIB_PTHREAD != 0
@ -174,13 +183,57 @@ validate_env_str(char *env)
}
#endif
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
#ifdef __NuttX__
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE * BH_KB] = { 0 };
#else
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
#endif
#if BH_HAS_DLFCN
typedef uint32 (*get_native_lib_func)(char **p_module_name,
NativeSymbol **p_native_symbols);
static uint32
load_and_register_native_libs(const char **native_lib_list,
uint32 native_lib_count,
void **native_handle_list)
{
uint32 i, native_handle_count = 0, n_native_symbols;
NativeSymbol *native_symbols;
char *module_name;
void *handle;
for (i = 0; i < native_lib_count; i++) {
/* open the native library */
if (!(handle = dlopen(native_lib_list[i], RTLD_NOW | RTLD_GLOBAL))
&& !(handle = dlopen(native_lib_list[i], RTLD_LAZY))) {
LOG_WARNING("warning: failed to load native library %s",
native_lib_list[i]);
continue;
}
/* lookup get_native_lib func */
get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib");
if (!get_native_lib) {
LOG_WARNING("warning: failed to lookup `get_native_lib` function "
"from native lib %s",
native_lib_list[i]);
dlclose(handle);
continue;
}
n_native_symbols = get_native_lib(&module_name, &native_symbols);
/* register native symbols */
if (!(n_native_symbols > 0 && module_name && native_symbols
&& wasm_runtime_register_natives(module_name, native_symbols,
n_native_symbols))) {
LOG_WARNING("warning: failed to register native lib %s",
native_lib_list[i]);
dlclose(handle);
continue;
}
native_handle_list[native_handle_count++] = handle;
}
return native_handle_count;
}
#endif /* BH_HAS_DLFCN */
#if WASM_ENABLE_MULTI_MODULE != 0
static char *
@ -224,6 +277,14 @@ moudle_destroyer(uint8 *buffer, uint32 size)
}
#endif /* WASM_ENABLE_MULTI_MODULE */
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
#ifdef __NuttX__
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE * BH_KB] = { 0 };
#else
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
#endif
int
main(int argc, char *argv[])
{
@ -249,6 +310,12 @@ main(int argc, char *argv[])
const char *addr_pool[8] = { NULL };
uint32 addr_pool_size = 0;
#endif
#if BH_HAS_DLFCN
const char *native_lib_list[8] = { NULL };
uint32 native_lib_count = 0;
void *native_handle_list[8] = { NULL };
uint32 native_handle_count = 0, native_handle_idx;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
char *ip_addr = NULL;
/* int platform_port = 0; */
@ -337,6 +404,18 @@ main(int argc, char *argv[])
}
}
#endif /* WASM_ENABLE_LIBC_WASI */
#if BH_HAS_DLFCN
else if (!strncmp(argv[0], "--native-lib=", 13)) {
if (argv[0][13] == '\0')
return print_help();
if (native_lib_count >= sizeof(native_lib_list) / sizeof(char *)) {
printf("Only allow max native lib number %d\n",
(int)(sizeof(native_lib_list) / sizeof(char *)));
return -1;
}
native_lib_list[native_lib_count++] = argv[0] + 13;
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
else if (!strncmp(argv[0],
"--module-path=", strlen("--module-path="))) {
@ -407,6 +486,11 @@ main(int argc, char *argv[])
bh_log_set_verbose_level(log_verbose_level);
#endif
#if BH_HAS_DLFCN
native_handle_count = load_and_register_native_libs(
native_lib_list, native_lib_count, native_handle_list);
#endif
/* load WASM byte buffer from WASM bin file */
if (!(wasm_file_buf =
(uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size)))
@ -481,6 +565,13 @@ fail2:
os_munmap(wasm_file_buf, wasm_file_size);
fail1:
#if BH_HAS_DLFCN
/* unload the native libraries */
for (native_handle_idx = 0; native_handle_idx < native_handle_count;
native_handle_idx++)
dlclose(native_handle_list[native_handle_idx]);
#endif
/* destroy runtime environment */
wasm_runtime_destroy();
return 0;

View File

@ -40,7 +40,7 @@ print_help()
printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
printf(" --module-path= Indicate a module search path. default is current\n"
printf(" --module-path=<path> Indicate a module search path. default is current\n"
" directory('./')\n");
#endif
#if WASM_ENABLE_LIB_PTHREAD != 0

View File

@ -28,6 +28,7 @@ usage ()
echo " $0 $QEMU_XTENSA_TARGET"
echo " $0 $QEMU_RISCV64_TARGET"
echo " $0 $QEMU_RISCV32_TARGET"
echo " $0 $QEMU_ARC_TARGET"
exit 1
}

View File

@ -45,7 +45,7 @@ static char *uart_device = "/dev/ttyS2";
static int baudrate = B115200;
#endif
extern void
extern bool
init_sensor_framework();
extern void
exit_sensor_framework();
@ -175,9 +175,11 @@ func_server_mode(void *arg)
struct sockaddr_in serv_addr, cli_addr;
int n;
char buff[MAX];
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, 0);
/* First call to socket() function */
@ -525,10 +527,14 @@ iwasm_main(int argc, char *argv[])
hal_init();
init_sensor_framework();
if (!init_sensor_framework()) {
goto fail2;
}
// timer manager
init_wasm_timer();
/* timer manager */
if (!init_wasm_timer()) {
goto fail3;
}
#ifndef CONNECTION_UART
if (server_mode)
@ -544,7 +550,11 @@ iwasm_main(int argc, char *argv[])
app_manager_startup(&interface);
exit_wasm_timer();
fail3:
exit_sensor_framework();
fail2:
wgl_exit();
exit_connection_framework();

View File

@ -16,7 +16,7 @@
#include "display.h"
#include "lvgl.h"
extern void
extern bool
init_sensor_framework();
extern void
exit_sensor_framework();
@ -177,12 +177,14 @@ iwasm_main()
wgl_init();
hal_init();
// timer manager
init_wasm_timer();
/* timer manager */
if (!init_wasm_timer()) {
goto fail;
}
// TODO:
app_manager_startup(&interface);
fail:
wasm_runtime_destroy();
return -1;
}

View File

@ -43,7 +43,7 @@ static char *uart_device = "/dev/ttyS2";
static int baudrate = B115200;
#endif
extern void
extern bool
init_sensor_framework();
extern void
exit_sensor_framework();
@ -169,9 +169,11 @@ func_server_mode(void *arg)
struct sockaddr_in serv_addr, cli_addr;
int n;
char buff[MAX];
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, 0);
/* First call to socket() function */
@ -505,10 +507,14 @@ iwasm_main(int argc, char *argv[])
extern void display_SDL_init();
display_SDL_init();
init_sensor_framework();
if (!init_sensor_framework()) {
goto fail2;
}
// timer manager
init_wasm_timer();
/* timer manager */
if (!init_wasm_timer()) {
goto fail3;
}
#ifndef CONNECTION_UART
if (server_mode)
@ -524,7 +530,11 @@ iwasm_main(int argc, char *argv[])
app_manager_startup(&interface);
exit_wasm_timer();
fail3:
exit_sensor_framework();
fail2:
exit_connection_framework();
fail1:

View File

@ -20,7 +20,7 @@
#include <drivers/uart.h>
#include <device.h>
extern void
extern bool
init_sensor_framework();
extern void
exit_sensor_framework();
@ -118,12 +118,14 @@ iwasm_main()
display_init();
// timer manager
init_wasm_timer();
/* timer manager */
if (!init_wasm_timer()) {
goto fail;
}
// TODO:
app_manager_startup(&interface);
fail:
wasm_runtime_destroy();
return -1;
}

View File

@ -70,5 +70,5 @@ set (RUNTIME_SOURCE_ALL
${UNCOMMON_SHARED_SOURCE}
)
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
target_link_libraries(iwasm vmlib -lpthread -lm)
target_link_libraries(iwasm vmlib -lpthread -lm -ldl)

View File

@ -0,0 +1,76 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.0)
project(native_lib)
################ runtime settings ##############
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
if (APPLE)
add_definitions(-DBH_PLATFORM_DARWIN)
endif ()
# Reset default linker flags
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# WAMR features switch
# Set WAMR_BUILD_TARGET, currently values supported are:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
else ()
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
endif ()
endif ()
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_LIBC_BUILTIN 1)
set (WAMR_BUILD_FAST_INTERP 1)
# compiling and linking flags
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
endif ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
# build out vmlib
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
################ wamr runtime ###################
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
set (RUNTIME_SOURCE_ALL
${WAMR_ROOT_DIR}/product-mini/platforms/posix/main.c
${UNCOMMON_SHARED_SOURCE}
)
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
target_link_libraries(iwasm vmlib -lpthread -lm -ldl)
################ native libraries ###############
add_library (test_add SHARED test_add.c)
add_library (test_sqrt SHARED test_sqrt.c)
################ wasm application ###############
add_subdirectory(wasm-app)

View File

@ -0,0 +1,59 @@
# "native-lib" sample introduction
This sample demonstrates how to write required interfaces in native library, build it into a shared library and register the shared library to iwasm.
The native library should provide `get_native_lib` API for iwasm to return the native library info, including the module name, the native symbol list and the native symbol count, so that iwasm can use them to regiter the native library, for example:
```C
static int
foo_wrapper(wasm_exec_env_t *exec_env, int x, int y)
{
return x + y;
}
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL }
static NativeSymbol native_symbols[] = {
REG_NATIVE_FUNC(foo, "(ii)i")
};
uint32_t
get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols)
{
*p_module_name = "env";
*p_native_symbols = native_symbols;
return sizeof(native_symbols) / sizeof(NativeSymbol);
}
```
## Preparation
Please install WASI SDK, download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`.
## Build the sample
```bash
mkdir build
cd build
cmake ..
make
```
`iwasm`, one wasm module `test.wasm` and two shared libraries `libtest_add.so`, `libtest_sqrt.so`
will be generated.
## Run workload
```bash
cd build
./iwasm --native-lib=libtest_add.so --native-lib=libtest_sqrt.so wasm-app/test.wasm
```
The output is:
```bash
Hello World!
10 + 20 = 30
sqrt(10, 20) = 500
```

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <stdlib.h>
#include "wasm_export.h"
static int
test_add_wrapper(wasm_exec_env_t *exec_env, int x, int y)
{
return x + y;
}
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL }
static NativeSymbol native_symbols[] = {
REG_NATIVE_FUNC(test_add, "(ii)i")
};
/* clang-format on */
uint32_t
get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols)
{
*p_module_name = "env";
*p_native_symbols = native_symbols;
return sizeof(native_symbols) / sizeof(NativeSymbol);
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <stdlib.h>
#include "wasm_export.h"
static int
test_sqrt_wrapper(wasm_exec_env_t *exec_env, int x, int y)
{
return x * x + y * y;
}
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL }
static NativeSymbol native_symbols[] = {
REG_NATIVE_FUNC(test_sqrt, "(ii)i")
};
/* clang-format on */
uint32_t
get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols)
{
*p_module_name = "env";
*p_native_symbols = native_symbols;
return sizeof(native_symbols) / sizeof(NativeSymbol);
}

View File

@ -0,0 +1,35 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.0)
project(wasm-app)
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
if (APPLE)
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
set (CMAKE_C_LINK_FLAGS "")
set (CMAKE_CXX_LINK_FLAGS "")
endif ()
set (CMAKE_SYSTEM_PROCESSOR wasm32)
set (CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot)
if (NOT DEFINED WASI_SDK_DIR)
set (WASI_SDK_DIR "/opt/wasi-sdk")
endif ()
set (CMAKE_C_FLAGS "-nostdlib")
set (CMAKE_C_COMPILER_TARGET "wasm32")
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
set (CMAKE_EXE_LINKER_FLAGS
"-Wl,--max-memory=131072 -z stack-size=8192 \
-Wl,--no-entry,--strip-all \
-Wl,--export=__main_argc_argv \
-Wl,--export=__heap_base,--export=__data_end \
-Wl,--allow-undefined"
)
add_executable(test.wasm main.c)
target_link_libraries(test.wasm)

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <stdlib.h>
int
test_add(int x, int y);
int
test_sqrt(int x, int y);
int
main(int argc, char **argv)
{
int x = 10, y = 20, res;
printf("Hello World!\n");
res = test_add(x, y);
printf("%d + %d = %d\n", x, y, res);
res = test_sqrt(x, y);
printf("sqrt(%d, %d) = %d\n", x, y, res);
return 0;
}

View File

@ -30,8 +30,8 @@ local_chk_externref(wasm_exec_env_t exec_env, int32 index, uintptr_t externref)
/* clang-format off */
static NativeSymbol native_symbols[] = {
{ "native-cmp-externref", local_cmp_externref, "(II)i", NULL },
{ "native-chk-externref", local_chk_externref, "(iI)i", NULL },
{ "native-cmp-externref", local_cmp_externref, "(rr)i", NULL },
{ "native-chk-externref", local_chk_externref, "(ir)i", NULL },
};
/* clang-format on */

View File

@ -45,7 +45,7 @@ static char *uart_device = "/dev/ttyS2";
static int baudrate = B115200;
#endif
extern void
extern bool
init_sensor_framework();
extern void
exit_sensor_framework();
@ -178,9 +178,11 @@ func_server_mode(void *arg)
struct sockaddr_in serv_addr, cli_addr;
int n;
char buff[MAX];
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, 0);
/* First call to socket() function */
@ -516,16 +518,21 @@ iwasm_main(int argc, char *argv[])
return -1;
}
/* timer manager */
init_wasm_timer();
/* connection framework */
if (!init_connection_framework()) {
goto fail1;
}
/* sensor framework */
init_sensor_framework();
if (!init_sensor_framework()) {
goto fail2;
}
/* timer manager */
if (!init_wasm_timer()) {
goto fail3;
}
/* add the sys sensor objects */
add_sys_sensor("sensor_test1", "This is a sensor for test", 0, 1000,
read_test_sensor, config_test_sensor);
@ -547,7 +554,11 @@ iwasm_main(int argc, char *argv[])
app_manager_startup(&interface);
exit_wasm_timer();
fail3:
exit_sensor_framework();
fail2:
exit_connection_framework();
fail1:

View File

@ -162,4 +162,4 @@ set (RUNTIME_SOURCE_ALL
${UNCOMMON_SHARED_SOURCE}
)
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
target_link_libraries(iwasm vmlib -lpthread -lm)
target_link_libraries(iwasm vmlib -lpthread -lm -ldl)

View File

@ -2,8 +2,8 @@
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <arpa/inet.h>
#include <assert.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdbool.h>
@ -109,7 +109,8 @@ run_as_client(void *arg)
{
int sock = -1;
struct sockaddr_in addr = { 0 };
char buf[256] = { 0 };
/* buf of server is 106 bytes */
char buf[110] = { 0 };
struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 };
ssize_t recv_len = 0;
@ -145,11 +146,11 @@ run_as_client(void *arg)
}
printf("Receive %ld bytes successlly!\n", recv_len);
printf("Data:\n");
assert(recv_len == 106);
uint8_t i = 0;
printf("Data:\n");
char *s = msg.msg_iov->iov_base;
for (i = 0; i < 6; i++) {
while (strlen(s) > 0) {
printf(" %s\n", s);
s += strlen(s) + 1;
}

View File

@ -77,9 +77,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -16,52 +16,61 @@ static const byte_t *
get_memory_data(uint32_t offset, uint32_t length);
static bool
call_wasm_function(uint32_t export_id,
const wasm_val_vec_t *args,
wasm_val_vec_t *results,
const char *name);
call_wasm_function(uint32_t export_id, const wasm_val_vec_t *args,
wasm_val_vec_t *results, const char *name);
/************************ IMPORTED FUNCTIONS **************************/
// (nil) -> i32
#define FUNCTION_TYPE_NIL_I32 wasm_functype_new_0_1(wasm_valtype_new_i32())
// (i32, i32) -> nil
#define FUNCTION_TYPE_I32X2_NIL \
#define FUNCTION_TYPE_I32X2_NIL \
wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())
/* IMPORT FUNCTION LIST */
#define IMPORT_FUNCTION_LIST(V) \
V(get_pairs, 0, FUNCTION_TYPE_NIL_I32) \
#define IMPORT_FUNCTION_LIST(V) \
V(get_pairs, 0, FUNCTION_TYPE_NIL_I32) \
V(log, 1, FUNCTION_TYPE_I32X2_NIL)
/* EXPORT FUNCTION LIST */
#define EXPORT_FUNCTION_LIST(V) \
V(on_start) \
V(on_stop) \
V(malloc) \
#define EXPORT_FUNCTION_LIST(V) \
V(on_start) \
V(on_stop) \
V(malloc) \
V(free)
enum EXPORT_ITEM_NAME {
#define DEFINE_ENUM(name) e_##name,
EXPORT_FUNCTION_LIST(DEFINE_ENUM)
#undef DEFINE_ENUM
e_MEMORY,
e_MEMORY,
};
#define DEFINE_FUNCTION(name) \
wasm_trap_t *STUB_##name(const wasm_val_vec_t* args, wasm_val_vec_t* results)
#define DEFINE_FUNCTION(name) \
wasm_trap_t *STUB_##name(const wasm_val_vec_t *args, \
wasm_val_vec_t *results)
#define DEFINE_EMPTY_FUNCTION(name) \
DEFINE_FUNCTION(name) \
{ \
printf("[WASM -> NATIVE] calling back %s\n", __FUNCTION__); \
return NULL; \
#define DEFINE_EMPTY_FUNCTION(name) \
DEFINE_FUNCTION(name) \
{ \
printf("[WASM -> NATIVE] calling back %s\n", __FUNCTION__); \
return NULL; \
}
#undef DEFINE_EMPTY_FUNCTION
DEFINE_FUNCTION(get_pairs)
{
call_wasm_function(e_malloc, args, results, "malloc");
wasm_val_vec_t as = { 0 };
wasm_val_t data[1] = { WASM_I32_VAL(10) };
wasm_val_vec_new(&as, 1, data);
if (as.data == NULL) {
printf("ERROR: create parameters failed\n");
return NULL;
}
call_wasm_function(e_malloc, &as, results, "malloc");
wasm_val_vec_delete(&as);
return NULL;
}
@ -91,9 +100,8 @@ DEFINE_FUNCTION(log)
}
/**********************************************************************/
// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j Export X.wasm"
// -1: memory
// 0-32: functions
// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j
// Export X.wasm" -1: memory 0-32: functions
static own wasm_extern_vec_t exports = { 0 };
static const byte_t *
@ -117,10 +125,8 @@ get_memory_data(uint32_t offset, uint32_t length)
}
static bool
call_wasm_function(uint32_t export_id,
const wasm_val_vec_t *args,
wasm_val_vec_t *results,
const char *name)
call_wasm_function(uint32_t export_id, const wasm_val_vec_t *args,
wasm_val_vec_t *results, const char *name)
{
const wasm_func_t *function;
wasm_trap_t *trap;
@ -169,9 +175,28 @@ main(int argc, const char *argv[])
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {
@ -196,38 +221,38 @@ main(int argc, const char *argv[])
// Create external functions.
printf("Creating callback...\n");
#define IMPORT_FUNCTION_VARIABLE_NAME(name, ...) \
#define IMPORT_FUNCTION_VARIABLE_NAME(name, ...) \
own wasm_func_t *function_##name = NULL;
IMPORT_FUNCTION_LIST(IMPORT_FUNCTION_VARIABLE_NAME)
#undef IMPORT_FUNCTION_VARIABLE_NAME
#define CREATE_WASM_FUNCTION(name, index, CREATE_FUNC_TYPE) \
{ \
own wasm_functype_t *type = CREATE_FUNC_TYPE; \
if (!(function_##name = wasm_func_new(store, type, STUB_##name))) { \
printf("> Error creating new function\n"); \
return 1; \
} \
wasm_functype_delete(type); \
#define CREATE_WASM_FUNCTION(name, index, CREATE_FUNC_TYPE) \
{ \
own wasm_functype_t *type = CREATE_FUNC_TYPE; \
if (!(function_##name = wasm_func_new(store, type, STUB_##name))) { \
printf("> Error creating new function\n"); \
return 1; \
} \
wasm_functype_delete(type); \
}
IMPORT_FUNCTION_LIST(CREATE_WASM_FUNCTION)
#undef CREATE_WASM_FUNCTION
wasm_extern_t *fs[10] = {0};
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
wasm_extern_t *fs[10] = { 0 };
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
fs[index] = wasm_func_as_extern(function_##name);
IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST)
#undef ADD_TO_FUNCTION_LIST
wasm_extern_vec_t imports = WASM_ARRAY_VEC(fs);
own wasm_instance_t *instance =
wasm_instance_new(store, module, &imports, NULL);
wasm_instance_new(store, module, &imports, NULL);
if (!instance) {
printf("> Error instantiating module!\n");
return 1;
}
#define DESTROY_WASM_FUNCITON(name, index, ...) \
#define DESTROY_WASM_FUNCITON(name, index, ...) \
wasm_func_delete(function_##name);
IMPORT_FUNCTION_LIST(DESTROY_WASM_FUNCITON)
#undef DESTROY_WASM_FUNCITON

View File

@ -21,9 +21,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -64,9 +64,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -34,9 +34,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -139,9 +139,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -110,9 +110,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -111,9 +111,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -90,9 +90,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -47,9 +47,28 @@ int main(int argc, const char* argv[]) {
printf("> Error loading module!\n");
return 1;
}
fseek(file, 0L, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0L, SEEK_SET);
int ret = fseek(file, 0L, SEEK_END);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
long file_size = ftell(file);
if (file_size == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
ret = fseek(file, 0L, SEEK_SET);
if (ret == -1) {
printf("> Error loading module!\n");
fclose(file);
return 1;
}
wasm_byte_vec_t binary;
wasm_byte_vec_new_uninitialized(&binary, file_size);
if (fread(binary.data, file_size, 1, file) != 1) {

View File

@ -1113,10 +1113,6 @@ fail:
hooks->deallocate(buffer->buffer);
}
if (printed != NULL) {
hooks->deallocate(printed);
}
return NULL;
}
@ -1818,9 +1814,9 @@ add_item_to_array(cJSON *array, cJSON *item)
}
/* Add item to array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
{
add_item_to_array(array, item);
return add_item_to_array(array, item);
}
#if defined(__clang__) \
@ -1878,37 +1874,39 @@ add_item_to_object(cJSON *const object, const char *const string,
return add_item_to_array(object, item);
}
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
{
add_item_to_object(object, string, item, &global_hooks, false);
return add_item_to_object(object, string, item, &global_hooks, false);
}
/* Add an item to an object with constant string as key */
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
{
add_item_to_object(object, string, item, &global_hooks, true);
return add_item_to_object(object, string, item, &global_hooks, true);
}
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
{
if (array == NULL) {
return;
return false;
}
add_item_to_array(array, create_reference(item, &global_hooks));
return add_item_to_array(array, create_reference(item, &global_hooks));
}
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
{
if ((object == NULL) || (string == NULL)) {
return;
return false;
}
add_item_to_object(object, string, create_reference(item, &global_hooks),
&global_hooks, false);
return add_item_to_object(object, string,
create_reference(item, &global_hooks),
&global_hooks, false);
}
CJSON_PUBLIC(cJSON *)
@ -2093,19 +2091,18 @@ cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
}
/* Replace array/object items with new ones. */
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
{
cJSON *after_inserted = NULL;
if (which < 0) {
return;
return false;
}
after_inserted = get_array_item(array, (size_t)which);
if (after_inserted == NULL) {
add_item_to_array(array, newitem);
return;
return add_item_to_array(array, newitem);
}
newitem->next = after_inserted;
@ -2117,6 +2114,7 @@ cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
else {
newitem->prev->next = newitem;
}
return true;
}
CJSON_PUBLIC(cJSON_bool)

View File

@ -247,20 +247,21 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and
* will definitely survive the cJSON object. WARNING: When this function was
* used, make sure to always check that (item->type & cJSON_StringIsConst) is
* zero before writing to `item->string` */
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
* existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool)
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
@ -278,7 +279,7 @@ CJSON_PUBLIC(void)
cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void)
CJSON_PUBLIC(cJSON_bool)
cJSON_InsertItemInArray(
cJSON *array, int which,
cJSON *newitem); /* Shifts pre-existing items to the right. */

View File

@ -808,7 +808,8 @@ int main(int argc, char *argv[])
}
if (g_conn_fd == -1) {
if (init() != 0) {
if ((init() != 0)
|| (g_conn_fd == -1)) {
sleep(1);
continue;
}

View File

@ -125,6 +125,7 @@ bool
udp_send(const char *address, int port, const char *buf, int len)
{
int sockfd;
ssize_t size_sent;
struct sockaddr_in servaddr;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
@ -136,11 +137,11 @@ udp_send(const char *address, int port, const char *buf, int len)
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = INADDR_ANY;
sendto(sockfd, buf, len, MSG_CONFIRM, (const struct sockaddr *)&servaddr,
sizeof(servaddr));
size_sent = sendto(sockfd, buf, len, MSG_CONFIRM,
(const struct sockaddr *)&servaddr, sizeof(servaddr));
close(sockfd);
return true;
return (size_sent != -1) ? true : false;
}
bool

View File

@ -203,7 +203,7 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,bounds-strict,alignment \
-fno-sanitize-recover")
set(lib_ubsan ubsan)
set(lib_ubsan -fsanitize=undefined)
endif()
else ()
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
@ -211,7 +211,7 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,alignment \
-fno-sanitize-recover")
set(lib_ubsan ubsan)
set(lib_ubsan -fsanitize=undefined)
endif()
endif()
endif ()

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _WAMR_LIBC_STDARG_H
#define _WAMR_LIBC_STDARG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _VA_LIST
typedef __builtin_va_list va_list;
#define _VA_LIST
#endif
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define __va_copy(d, s) __builtin_va_copy(d, s)
#ifdef __cplusplus
}
#endif
#endif /* end of _WAMR_LIBC_STDARG_H */

View File

@ -26,6 +26,9 @@ wasm_get_sys_tick_ms
printf
sprintf
snprintf
vprintf
vsprintf
vsnprintf
puts
putchar
memcmp