mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-11 20:21:11 +00:00
Merge main into dev/fast_jit
This commit is contained in:
commit
4746eaa029
|
@ -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",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "runtime_timer.h"
|
||||
|
||||
void
|
||||
bool
|
||||
init_wasm_timer();
|
||||
void
|
||||
exit_wasm_timer();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ check_sensor_timers();
|
|||
void
|
||||
reschedule_sensor_read();
|
||||
|
||||
void
|
||||
bool
|
||||
init_sensor_framework();
|
||||
void
|
||||
start_sensor_framework();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -529,7 +529,6 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
default:
|
||||
bh_assert(0);
|
||||
return false;
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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] = \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 *))
|
||||
{
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
76
samples/native-lib/CMakeLists.txt
Normal file
76
samples/native-lib/CMakeLists.txt
Normal 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)
|
59
samples/native-lib/README.md
Normal file
59
samples/native-lib/README.md
Normal 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
|
||||
```
|
32
samples/native-lib/test_add.c
Normal file
32
samples/native-lib/test_add.c
Normal 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);
|
||||
}
|
32
samples/native-lib/test_sqrt.c
Normal file
32
samples/native-lib/test_sqrt.c
Normal 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);
|
||||
}
|
35
samples/native-lib/wasm-app/CMakeLists.txt
Normal file
35
samples/native-lib/wasm-app/CMakeLists.txt
Normal 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)
|
29
samples/native-lib/wasm-app/main.c
Normal file
29
samples/native-lib/wasm-app/main.c
Normal 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;
|
||||
}
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
40
test-tools/host-tool/external/cJSON/cJSON.c
vendored
40
test-tools/host-tool/external/cJSON/cJSON.c
vendored
|
@ -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)
|
||||
|
|
13
test-tools/host-tool/external/cJSON/cJSON.h
vendored
13
test-tools/host-tool/external/cJSON/cJSON.h
vendored
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
27
wamr-sdk/app/libc-builtin-sysroot/include/stdarg.h
Normal file
27
wamr-sdk/app/libc-builtin-sysroot/include/stdarg.h
Normal 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 */
|
|
@ -26,6 +26,9 @@ wasm_get_sys_tick_ms
|
|||
printf
|
||||
sprintf
|
||||
snprintf
|
||||
vprintf
|
||||
vsprintf
|
||||
vsnprintf
|
||||
puts
|
||||
putchar
|
||||
memcmp
|
||||
|
|
Loading…
Reference in New Issue
Block a user