[dylink] Add an experimental shared-everything multiple modules link feature. (#1023)

By this patch, an experimental shared-everything modules linking is supported, typically
user could use the feature to dlopen a wasm/aot module, then get the funcref by dlsym, and
call the target function by call indirect instr. Of course, a dlclose is supported too.

Currently, root module could be a regular module, wasi module, or AssemblyScript module;
dependency module MUST be a module built followed the proposal "dynamical linking", that means
it should contain a new dylink section and no mem allocator function exported. User could
get it by clang or emcc. New iwasm switch --enable-dopen is used for enabling the feature and
choosing the launch mode. see the iwasm -h for details.

Multiple modules feature is not well tested, there should be some cases not covered.

Co-authored-by: jhe <hejie.he@antgroup.com>
This commit is contained in:
Jie He 2022-02-28 18:13:36 +08:00 committed by GitHub
parent 16ebfc3781
commit be2b561935
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 10137 additions and 1593 deletions

View File

@ -1,3 +1,19 @@
### Note
This branch includes an experimental feature, modules dynamic linking and some changes. I'm not convinced all of them will be merged into wamr trunk. And due to the feature needs, this branch is hard to full compatible with trunk,
especially aot mode, because I have to add a new section, dylink section, and other data to validate the aot file, including feature bit map and aot file compatibility checking etc. I list the changes below:
- A new feature, modules dynamic linking. based on it, users can dlopen a wasm/aot module, get a func id by dlsym, and call it using call indirect instr.
- Add a simple string interning implementation: a const string pool. because during modules linking, there are plenty of function/variable name resolving, especially string comparison manipulation. but I only rewrote the places the new feature touchs.
- Due to new const string pool, I changes the native wrapper functions register and resolving.
- Optimize calling native function by aot function, I move all address conversion operations from invoke_native into native wrapper, thus, wrapper function is the one has the knowledge which argument needs to do address conversion, and
all address conversion are gathered at wrapper, it's easy to implement a pre-process to auto-generated wrapper function.
- Calling function between modules has to do id resolving, this procedure is little bit complicated. firstly, I implemented a runtime builtin function to do it, but performance is poor. So that I added some opts, including some cases
go to LLVM IR implementation. in addition, a resolving cache is enabled to reduce the resolving cost, for easy to write LLVM IR, the cache is implemented a 16x2 matrix, each rows/cacheline has 2 cache entries to avoid conflict.
- Current dynamic linking mode, root module could be a regular wasm/aot module, wasi module or AssemblyScript module. iwasm will launch it according to parameter --enable-dlopen.
- last, this branch has passed single module spec test whatever enable dynamic linking or not, but multi module cases still need a lot of tests and maintain.
enjoy it.
WebAssembly Micro Runtime
=========================
[Build WAMR VM core](./doc/build_wamr.md) | [Embed WAMR](./doc/embed_wamr.md) | [Export native function](./doc/export_native_api.md) | [Build WASM applications](./doc/build_wasm_app.md) | [Samples](https://github.com/bytecodealliance/wasm-micro-runtime#samples)

View File

@ -11,6 +11,7 @@ elseif (WAMR_BUILD_TARGET STREQUAL "AMD_64")
add_definitions(-DBUILD_TARGET_AMD_64)
elseif (WAMR_BUILD_TARGET STREQUAL "X86_32")
add_definitions(-DBUILD_TARGET_X86_32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
if (WAMR_BUILD_TARGET MATCHES "(ARM.*)_VFP")
add_definitions(-DBUILD_TARGET_ARM_VFP)
@ -19,6 +20,7 @@ elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
add_definitions(-DBUILD_TARGET_ARM)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
endif ()
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
if (WAMR_BUILD_TARGET MATCHES "(THUMB.*)_VFP")
add_definitions(-DBUILD_TARGET_THUMB_VFP)
@ -27,23 +29,29 @@ elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
add_definitions(-DBUILD_TARGET_THUMB)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
endif ()
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
add_definitions(-DBUILD_TARGET_AARCH64)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
add_definitions(-DBUILD_TARGET_MIPS)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
add_definitions(-DBUILD_TARGET_XTENSA)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
add_definitions(-DBUILD_TARGET_RISCV64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "ARC")
add_definitions(-DBUILD_TARGET_ARC)
add_definitions(-DTARGET_32)
else ()
message (FATAL_ERROR "-- WAMR build target isn't set")
endif ()
@ -64,6 +72,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions (-m32)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
add_definitions(-DTARGET_32)
endif ()
endif ()
@ -111,6 +120,7 @@ else ()
endif ()
message ("-- Build Configurations:")
message(" hello configcommon ")
message (" Build as target ${WAMR_BUILD_TARGET}")
message (" CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
if (WAMR_BUILD_INTERP EQUAL 1)
@ -138,6 +148,13 @@ if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1)
else ()
message (" Libc builtin disabled")
endif ()
if (AS_HARDCODE_ABORT EQUAL 1)
add_definitions (-DAS_HARDCODE_ABORT=1)
message (" AS hardcode abort enabled")
else ()
add_definitions (-DAS_HARDCODE_ABORT=0)
message (" AS hardcode abort disabled")
endif ()
if (WAMR_BUILD_LIBC_UVWASI EQUAL 1)
message (" Libc WASI enabled with uvwasi implementation")
elseif (WAMR_BUILD_LIBC_WASI EQUAL 1)
@ -159,6 +176,13 @@ else ()
add_definitions (-DWASM_ENABLE_MULTI_MODULE=0)
message (" Multiple modules disabled")
endif ()
if (WAMR_BUILD_DYNAMIC_LINKING EQUAL 1)
add_definitions (-DWASM_ENABLE_DYNAMIC_LINKING=1)
message (" Dynamic linking enabled")
else ()
add_definitions (-DWASM_ENABLE_DYNAMIC_LINKING=0)
message (" Dynamic linking disabled")
endif ()
if (WAMR_BUILD_SPEC_TEST EQUAL 1)
add_definitions (-DWASM_ENABLE_SPEC_TEST=1)
message (" spec test compatible mode is on")

View File

@ -161,6 +161,18 @@ GET_U64_FROM_ADDR(uint32 *addr)
goto fail; \
} while (0)
#define csp_read_string(p, p_end, str) do { \
uint16 str_len; \
read_uint16(p, p_end, str_len); \
CHECK_BUF(p, p_end, str_len); \
if (!(str = wasm_runtime_records_const_string(\
runtime, (char*)p, str_len, \
error_buf, error_buf_size))) {\
goto fail; \
} \
p += str_len; \
} while (0)
/* Legal values for bin_type */
#define BIN_TYPE_ELF32L 0 /* 32-bit little endian */
#define BIN_TYPE_ELF32B 1 /* 32-bit big endian */
@ -213,34 +225,39 @@ const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
{
HashMap *set = module->const_str_set;
char *c_str, *value;
ConstStrDescription temp_key;
ConstStrDescription * key = NULL;
uint32 req_size = 0;
/* Create const string set if it isn't created */
if (!set
&& !(set = module->const_str_set = bh_hash_map_create(
32, false, (HashFunc)wasm_string_hash,
(KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
set_error_buf(error_buf, error_buf_size,
"create const string set failed");
return NULL;
}
temp_key.str = (void*)str;
temp_key.len = len;
temp_key.hash = 0;
/* Lookup const string set, use the string if found */
if (!(c_str = loader_malloc((uint32)len + 1, error_buf, error_buf_size))) {
return NULL;
}
bh_memcpy_s(c_str, (uint32)(len + 1), str, (uint32)len);
c_str[len] = '\0';
if ((value = bh_hash_map_find(set, c_str))) {
wasm_runtime_free(c_str);
if ((value = bh_hash_map_find(set, &temp_key))) {
return value;
}
if (!bh_hash_map_insert(set, c_str, c_str)) {
//req_size = (uint32)len + 1 + CONST_STR_HASHMAP_KEY_HEAD_LEN;
//req_size = (req_size > sizeof(ConstStrDescription)) ? req_size : sizeof(ConstStrDescription);
req_size = sizeof(ConstStrDescription) + (uint32)len + 1;
if (!(key = loader_malloc(req_size,
error_buf, error_buf_size))) {
return NULL;
}
//c_str = key->data;
c_str = (char*)(key + 1);
bh_memcpy_s(c_str, (uint32)(len + 1), str, (uint32)len);
key->str = c_str;
key->len = len;
key->hash = temp_key.hash;
if (!bh_hash_map_insert(set, key, c_str)) {
set_error_buf(error_buf, error_buf_size,
"insert string to hash map failed");
wasm_runtime_free(c_str);
wasm_runtime_free(key);
return NULL;
}
@ -1048,9 +1065,10 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module, bool is_load_from_file_buf,
char *error_buf, uint32 error_buf_size)
{
WASMRuntime * runtime = module->runtime;
const uint8 *buf = *p_buf;
AOTImportGlobal *import_globals;
uint64 size;
uint64 size = 0;
uint32 i, data_offset = 0;
#if WASM_ENABLE_LIBC_BUILTIN != 0
WASMGlobalImport tmp_global;
@ -1068,12 +1086,29 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
buf = (uint8 *)align_ptr(buf, 2);
read_uint8(buf, buf_end, import_globals[i].type);
read_uint8(buf, buf_end, import_globals[i].is_mutable);
read_string(buf, buf_end, import_globals[i].module_name);
read_string(buf, buf_end, import_globals[i].global_name);
//read_uint16(buf, buf_end, name_len);
//CHECK_BUF(buf, buf_end, name_len);
//if (!(key = wasm_runtime_records_const_string(module->runtime, (const char*)buf, name_len, error_buf, error_buf_size))) {
// return false;
//}
//import_globals[i].module_name = key;
//buf += name_len;
//read_uint16(buf, buf_end, name_len);
//CHECK_BUF(buf, buf_end, name_len);
//if (!(key = wasm_runtime_records_const_string(module->runtime, (const char*)buf, name_len, error_buf, error_buf_size))) {
// return false;
//}
//import_globals[i].global_name = key->str;
//buf += name_len;
csp_read_string(buf, buf_end, import_globals[i].module_name);
csp_read_string(buf, buf_end, import_globals[i].global_name);
//import_globals[i].global_name = key->str;
#if WASM_ENABLE_LIBC_BUILTIN != 0
if (wasm_native_lookup_libc_builtin_global(
import_globals[i].module_name, import_globals[i].global_name,
import_globals[i].module_name->str,
import_globals[i].global_name->str,
&tmp_global)) {
if (tmp_global.type != import_globals[i].type
|| tmp_global.is_mutable != import_globals[i].is_mutable) {
@ -1081,12 +1116,20 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
"incompatible import type");
return false;
}
bh_assert(import_globals[i].is_mutable == false);
import_globals[i].global_data_linked =
tmp_global.global_data_linked;
}
#endif
if (!import_globals[i].is_mutable) {
import_globals[i].size = wasm_value_type_size(import_globals[i].type);
} else {
// mutable import, a pointer will be saved into global data
// Note: compiler also should generate global var access instr based on the same offset.
import_globals[i].size = sizeof(void*);
}
import_globals[i].data_offset = data_offset;
data_offset += import_globals[i].size;
module->global_data_size += import_globals[i].size;
@ -1213,7 +1256,7 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
const char *module_name, *field_name;
WASMRuntime * runtime = module->runtime;
const uint8 *buf = *p_buf;
AOTImportFunc *import_funcs;
uint64 size;
@ -1233,21 +1276,18 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
set_error_buf(error_buf, error_buf_size, "unknown type");
return false;
}
import_funcs[i].func_type =
module->func_types[import_funcs[i].func_type_index];
read_string(buf, buf_end, import_funcs[i].module_name);
read_string(buf, buf_end, import_funcs[i].func_name);
import_funcs[i].func_type = module->func_types[import_funcs[i].func_type_index];
csp_read_string(buf, buf_end, import_funcs[i].module_name);
csp_read_string(buf, buf_end, import_funcs[i].func_name);
module_name = import_funcs[i].module_name;
field_name = import_funcs[i].func_name;
import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol(
module_name, field_name, import_funcs[i].func_type,
import_funcs[i].module_name, &import_funcs[i].func_name, import_funcs[i].func_type,
&import_funcs[i].signature, &import_funcs[i].attachment,
&import_funcs[i].call_conv_raw);
#if WASM_ENABLE_LIBC_WASI != 0
if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
|| !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1"))
if (import_funcs[i].module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_unstable)
|| import_funcs[i].module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_snapshot_preview1))
module->is_wasi_module = true;
#endif
}
@ -1372,6 +1412,83 @@ fail:
return false;
}
static bool
load_dylink_section(const uint8 *buf, const uint8 *buf_end,
AOTModule *module,
char *error_buf, uint32 error_buf_size)
{
WASMRuntime * runtime = module->runtime;
const uint8 *p = buf, *p_end = buf_end;
uint32 size = buf_end - buf;
WASMDylinkSection * dylink_section = NULL;
WASMDylinkSection tmp_dylink_section;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
const ConstStrDescription * key = NULL;
AOTModule* dependency_module = NULL;
#endif
memset(&tmp_dylink_section, 0, sizeof(WASMDylinkSection));
if (buf == buf_end)
return true;
if (size < (sizeof(uint32) * 5))
return false;
read_uint32(p, p_end, tmp_dylink_section.memory_size);
read_uint32(p, p_end, tmp_dylink_section.memory_alignment);
read_uint32(p, p_end, tmp_dylink_section.table_size);
read_uint32(p, p_end, tmp_dylink_section.memory_alignment);
read_uint32(p, p_end, tmp_dylink_section.needed_dylib_count);
// calculate the total size which all entries will take.
size = tmp_dylink_section.needed_dylib_count * sizeof(ConstStrDescription*);
size += sizeof(WASMDylinkSection);
dylink_section = (WASMDylinkSection*)loader_malloc(size, error_buf, error_buf_size);
if (!dylink_section)
return false;
bh_memcpy_s(dylink_section, sizeof(WASMDylinkSection), &tmp_dylink_section,
sizeof(WASMDylinkSection));
for (uint32 i = 0; i < dylink_section->needed_dylib_count; i ++) {
csp_read_string(p, p_end, dylink_section->needed_dylib_entries[i]);
//read_uint16(p, p_end, name_len);
//CHECK_BUF(p, p_end, name_len);
//key = wasm_runtime_records_const_string(runtime, (const char*)p, name_len, error_buf, error_buf_size);
//if (!key) {
// wasm_runtime_free(dylink_section);
// return false;
//}
//p += name_len;
//dylink_section->needed_dylib_entries[i] = key;
if (!runtime->config.need_load_dependencies)
continue;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
key = dylink_section->needed_dylib_entries[i];
dependency_module = (AOTModule*)load_implicit_dependency_module((const WASMModuleCommon *)module,
(ConstStrDescription *)key,
error_buf, error_buf_size);
if (!dependency_module) {
return false;
}
#endif
}
module->dylink_section = dylink_section;
return true;
fail:
if (dylink_section)
wasm_runtime_free(dylink_section);
return false;
}
static bool
load_init_data_section(const uint8 *buf, const uint8 *buf_end,
AOTModule *module, bool is_load_from_file_buf,
@ -1607,6 +1724,9 @@ load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
AOTExport *exports;
uint64 size;
uint32 i;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMRuntime * runtime = module->runtime;
#endif
/* Allocate memory */
size = sizeof(AOTExport) * (uint64)module->export_count;
@ -1620,6 +1740,27 @@ load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
read_uint32(buf, buf_end, exports[i].index);
read_uint8(buf, buf_end, exports[i].kind);
read_string(buf, buf_end, exports[i].name);
switch (exports[i].kind) {
case EXPORT_KIND_FUNC:
module->export_func_count++;
break;
case EXPORT_KIND_GLOBAL:
module->export_global_count++;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (!strcmp(exports[i].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_stack_pointer)) ||
!strcmp(exports[i].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer)))
module->export_sp_global_id = i;
#endif
break;
case EXPORT_KIND_TABLE:
module->export_tab_count++;
break;
case EXPORT_KIND_MEMORY:
module->export_mem_count++;
break;
default:
return false;
}
#if 0 /* TODO: check kind and index */
if (export_funcs[i].index >=
module->func_count + module->import_func_count) {
@ -1631,6 +1772,7 @@ load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
}
*p_buf = buf;
return true;
fail:
return false;
@ -2280,6 +2422,11 @@ load_from_sections(AOTModule *module, AOTSection *sections,
error_buf_size))
return false;
break;
case AOT_SECTION_TYPE_DYLINK:
if (!load_dylink_section(buf, buf_end, module,
error_buf, error_buf_size))
return false;
break;
case AOT_SECTION_TYPE_INIT_DATA:
if (!load_init_data_section(buf, buf_end, module,
is_load_from_file_buf, error_buf,
@ -2346,7 +2493,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
&& func_type->types[0] == VALUE_TYPE_I32
&& func_type->types[1] == VALUE_TYPE_I32) {
bh_assert(module->malloc_func_index == (uint32)-1);
module->malloc_func_index = func_index;
module->malloc_func_index = exports[i].index ;
LOG_VERBOSE("Found malloc function, name: %s, index: %u",
exports[i].name, exports[i].index);
}
@ -2363,7 +2510,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
WASMExport *export_tmp;
bh_assert(module->malloc_func_index == (uint32)-1);
module->malloc_func_index = func_index;
module->malloc_func_index = exports[i].index;
LOG_VERBOSE("Found malloc function, name: %s, index: %u",
exports[i].name, exports[i].index);
@ -2410,7 +2557,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
if (func_type->param_count == 1 && func_type->result_count == 0
&& func_type->types[0] == VALUE_TYPE_I32) {
bh_assert(module->free_func_index == (uint32)-1);
module->free_func_index = func_index;
module->free_func_index = exports[i].index;
LOG_VERBOSE("Found free function, name: %s, index: %u",
exports[i].name, exports[i].index);
}
@ -2448,6 +2595,27 @@ create_module(char *error_buf, uint32 error_buf_size)
module->module_type = Wasm_Module_AoT;
if (!(module->const_str_set =
bh_hash_map_create(64, false,
(HashFunc)const_str_hash,
(KeyEqualFunc)const_str_equal,
(ValueDestroyFunc)const_str_destroy_key,
NULL))) {
set_error_buf(error_buf, error_buf_size,
"create const string set failed");
wasm_runtime_free(module);
return NULL;
}
module->file_buf = NULL;
module->runtime = wasm_runtime_get_runtime();
#if WASM_ENABLE_DYNAMIC_LINKING != 0
// initial dependency related attributes.
module->implicit_dependency_modules_hmap = NULL;
module->ref_cnt = 0;
#endif
module->module_name = NULL;
return module;
}
@ -2485,6 +2653,7 @@ destroy_sections(AOTSection *section_list, bool destroy_aot_text)
}
}
#define AOT_HEADER_SIZE (sizeof(uint32) + sizeof(uint32) + sizeof(uint64) + sizeof(uint32))
static bool
resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count,
char *error_buf, uint32 error_buf_size)
@ -2493,7 +2662,7 @@ resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count,
uint32 section_type;
uint32 section_size = 0;
p += 8;
p += AOT_HEADER_SIZE;
while (p < p_end) {
read_uint32(p, p_end, section_type);
if (section_type <= AOT_SECTION_TYPE_SIGANATURE
@ -2543,7 +2712,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
module->native_symbol_count = native_symbol_count;
p += 8;
p += AOT_HEADER_SIZE;
while (p < p_end) {
read_uint32(p, p_end, section_type);
if (section_type < AOT_SECTION_TYPE_SIGANATURE
@ -2640,7 +2809,8 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
{
const uint8 *buf_end = buf + size;
const uint8 *p = buf, *p_end = buf_end;
uint32 magic_number, version;
uint32 magic_number, version, verification;
uint64 aot_features = 0, vm_features = 0;
AOTSection *section_list = NULL;
bool ret;
@ -2656,8 +2826,24 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
return false;
}
if (!create_sections(module, buf, size, &section_list, error_buf,
error_buf_size))
read_uint64(p, p_end, aot_features);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
vm_features |= AOT_FEATURE_ENABLE_DYNAMIC_LINKING;
#endif
if (aot_features != vm_features) {
set_error_buf(error_buf, error_buf_size, "unsupported features exist in VM or AOT file");
return false;
}
read_uint32(p, p_end, verification);
if (verification != offsetof(AOTModuleInstance, global_table_data.bytes)) {
set_error_buf(error_buf, error_buf_size, "AOT file built by imcompatiable AOT compiler");
return false;
}
bh_assert((p - buf) == AOT_HEADER_SIZE);
if (!create_sections(module, buf, size, &section_list,
error_buf, error_buf_size))
return false;
ret = load_from_sections(module, section_list, true, error_buf,
@ -2679,6 +2865,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
fail:
return false;
}
#undef AOT_HEADER_SIZE
AOTModule *
aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
@ -2839,11 +3026,16 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
goto fail3;
}
for (i = 0; i < comp_data->func_count; i++)
module->func_type_indexes[i] = comp_data->funcs[i]->func_type_index;
module->func_type_indexes[i] = comp_data->funcs[i].func_type_index;
module->export_count = comp_data->wasm_module->export_count;
module->exports = comp_data->wasm_module->exports;
module->export_func_count = comp_data->wasm_module->export_func_count;
module->export_tab_count = comp_data->wasm_module->export_tab_count;
module->export_mem_count = comp_data->wasm_module->export_mem_count;
module->export_global_count = comp_data->wasm_module->export_global_count;
module->start_func_index = comp_data->start_func_index;
if (comp_data->start_func_index != (uint32)-1) {
bh_assert(comp_data->start_func_index
@ -2909,14 +3101,6 @@ aot_convert_wasm_module(WASMModule *wasm_module, char *error_buf,
AOTCompOption option = { 0 };
char *aot_last_error;
comp_data = aot_create_comp_data(wasm_module);
if (!comp_data) {
aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL);
set_error_buf(error_buf, error_buf_size, aot_last_error);
return NULL;
}
option.is_jit_mode = true;
#if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true;
@ -2938,14 +3122,29 @@ aot_convert_wasm_module(WASMModule *wasm_module, char *error_buf,
option.enable_aux_stack_frame = true;
#endif
comp_ctx = aot_create_comp_context(comp_data, &option);
comp_ctx = aot_create_comp_context(&option);
if (!comp_ctx) {
aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL);
set_error_buf(error_buf, error_buf_size, aot_last_error);
return NULL;
}
comp_data = aot_create_comp_data(wasm_module, sizeof(void*));
if (!comp_data) {
aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL);
set_error_buf(error_buf, error_buf_size, aot_last_error);
goto fail1;
}
if (!aot_bind_comp_context_data(comp_ctx, comp_data)) {
aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL);
set_error_buf(error_buf, error_buf_size, aot_last_error);
goto fail2;
}
if (!aot_compile_wasm(comp_ctx)) {
aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL);
@ -2962,9 +3161,9 @@ aot_convert_wasm_module(WASMModule *wasm_module, char *error_buf,
return aot_module;
fail2:
aot_destroy_comp_context(comp_ctx);
fail1:
aot_destroy_comp_data(comp_data);
fail1:
aot_destroy_comp_context(comp_ctx);
return NULL;
}
#endif
@ -3071,6 +3270,12 @@ aot_unload(AOTModule *module)
}
#endif
if (module->dylink_section)
wasm_runtime_free(module->dylink_section);
if (module->file_buf)
wasm_runtime_free((void*)module->file_buf);
wasm_runtime_free(module);
}

View File

@ -108,8 +108,10 @@ typedef struct {
REG_SYM(aot_set_exception_with_id), \
REG_SYM(aot_invoke_native), \
REG_SYM(aot_call_indirect), \
REG_SYM(aot_call_indirect_with_type), \
REG_SYM(aot_enlarge_memory), \
REG_SYM(aot_set_exception), \
REG_SYM(aot_resolve_function), \
{ "memset", (void*)aot_memset}, \
{ "memmove", (void*)aot_memmove}, \
{ "memcpy", (void*)aot_memmove }, \

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@ typedef enum AOTExceptionID {
EXCE_UNDEFINED_ELEMENT,
EXCE_UNINITIALIZED_ELEMENT,
EXCE_CALL_UNLINKED_IMPORT_FUNC,
EXEC_CALL_UNLINKED_MODULE,
EXCE_NATIVE_STACK_OVERFLOW,
EXCE_UNALIGNED_ATOMIC,
EXCE_AUX_STACK_OVERFLOW,
@ -40,12 +41,13 @@ typedef enum AOTExceptionID {
typedef enum AOTSectionType {
AOT_SECTION_TYPE_TARGET_INFO = 0,
AOT_SECTION_TYPE_INIT_DATA = 1,
AOT_SECTION_TYPE_TEXT = 2,
AOT_SECTION_TYPE_FUNCTION = 3,
AOT_SECTION_TYPE_EXPORT = 4,
AOT_SECTION_TYPE_RELOCATION = 5,
AOT_SECTION_TYPE_SIGANATURE = 6,
AOT_SECTION_TYPE_DYLINK = 1,
AOT_SECTION_TYPE_INIT_DATA = 2,
AOT_SECTION_TYPE_TEXT = 3 ,
AOT_SECTION_TYPE_FUNCTION = 4,
AOT_SECTION_TYPE_EXPORT = 5,
AOT_SECTION_TYPE_RELOCATION = 6,
AOT_SECTION_TYPE_SIGANATURE = 7,
AOT_SECTION_TYPE_CUSTOM = 100,
} AOTSectionType;
@ -81,8 +83,8 @@ typedef struct AOTRelocationGroup {
} AOTRelocationGroup;
/* AOT function instance */
typedef struct AOTFunctionInstance {
char *func_name;
typedef struct AOTExportFunctionInstance {
const char *func_name;
uint32 func_index;
bool is_import_func;
union {
@ -93,7 +95,7 @@ typedef struct AOTFunctionInstance {
} func;
AOTImportFunc *func_import;
} u;
} AOTFunctionInstance;
} AOTExportFunctionInstance;
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
/* clang-format off */
@ -122,6 +124,8 @@ typedef struct AOTUnwindInfo {
typedef struct AOTModule {
uint32 module_type;
WASMDylinkSection * dylink_section;
/* import memories */
uint32 import_memory_count;
AOTImportMemory *import_memories;
@ -178,6 +182,10 @@ typedef struct AOTModule {
/* export info */
uint32 export_count;
uint32 export_func_count;
uint32 export_global_count;
uint32 export_mem_count;
uint32 export_tab_count;
AOTExport *exports;
/* start function index, -1 denotes no start function */
@ -246,6 +254,16 @@ typedef struct AOTModule {
/* is jit mode or not */
bool is_jit_mode;
const uint8 * file_buf;
WASMRuntime * runtime;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
/* directly implicit dependency modules of current module, e.g. dylink section */
HashMap *implicit_dependency_modules_hmap;
uint32 ref_cnt;
uint32 export_sp_global_id; // store the export id of stack_pointer after loading, so that no lookup again when linking
#endif
const ConstStrDescription * module_name;
#if WASM_ENABLE_JIT != 0
WASMModule *wasm_module;
AOTCompContext *comp_ctx;
@ -321,7 +339,28 @@ typedef struct AOTTableInstance {
typedef struct AOTModuleInstance {
uint32 module_type;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
//WASMModuleInstanceHead head;
// unique instance id in program scope, used to alloc table space currently.
uint32 inst_id;
WASMRuntime * runtime;
WASMProgramInstance * program;
HashMap * local_implicit_dependency_modules_name_hmap;
DependencyModuleInitGlobals init_globals;
// explicit ref count, updated by dlopen/dlclose
uint32 exp_ref_cnt;
// implicit ref count, updated according to needed library entries
uint32 imp_ref_cnt;
// workround here, for compatiable with aot instance memory layout
#ifdef TARGET_32
uint32 padding_runtime;
uint32 padding_program;
uint32 padding_imp_hmap;
#endif
uint32 padding_memory_count;
#endif
/* memories */
uint32 memory_count;
AOTPointer memories;
@ -339,6 +378,8 @@ typedef struct AOTModuleInstance {
AOTPointer global_data;
/* points to AOTTableInstance[] */
AOTPointer tables;
AOTPointer global_table_data_end;
/* function pointer array */
AOTPointer func_ptrs;
@ -346,15 +387,19 @@ typedef struct AOTModuleInstance {
AOTPointer func_type_indexes;
/* export info */
uint32 export_func_count;
uint32 export_global_count;
uint32 export_mem_count;
uint32 export_tab_count;
//uint32 export_func_count;
//uint32 export_global_count;
//uint32 export_mem_count;
//uint32 export_tab_count;
AOTPointer export_funcs;
AOTPointer export_globals;
AOTPointer export_memories;
AOTPointer export_tables;
AOTPointer malloc_func;
AOTPointer retain_func;
AOTPointer free_func;
/* The exception buffer for current thread. */
char cur_exception[128];
/* The custom data that can be set/get by
@ -497,9 +542,14 @@ aot_unload(AOTModule *module);
* @return return the instantiated AOT module instance, NULL if failed
*/
AOTModuleInstance*
aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 error_buf_size);
aot_instantiate(WASMProgramInstance * program, AOTModule *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
AOTModuleInstance*
aot_instantiate_dependency(AOTModule *module, WASMProgramInstance * program,
uint32 stack_size, DependencyModuleInitGlobals * init_globals);
#endif
/**
* Deinstantiate a AOT module instance, destroy the resources.
*
@ -519,7 +569,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst);
*
* @return the function instance found
*/
AOTFunctionInstance *
AOTExportFunctionInstance *
aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
const char *signature);
/**
@ -538,12 +588,12 @@ aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
* the caller can call aot_get_exception to get exception info.
*/
bool
aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
aot_call_function(WASMExecEnv *exec_env, AOTExportFunctionInstance *function,
unsigned argc, uint32 argv[]);
bool
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
AOTFunctionInstance *function,
AOTExportFunctionInstance *function,
unsigned argc, uint32 argv[]);
bool
@ -645,6 +695,15 @@ bool
aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
uint32 argc, uint32 *argv);
bool
aot_call_indirect_with_type(WASMExecEnv *exec_env,
uint32 tbl_idx, int32 table_elem_idx, uint32 type_idx,
uint32 argc, uint32 *argv);
bool
aot_resolve_function(WASMExecEnv *exec_env, uint32 import_func_id,
uint32 argc, uint32 *argv);
uint32
aot_get_plt_table_size();
@ -725,6 +784,20 @@ aot_dump_call_stack(WASMExecEnv *exec_env);
void
aot_dump_perf_profiling(const AOTModuleInstance *module_inst);
static inline AOTTableInstance *
aot_get_table_inst(const AOTModuleInstance *module_inst, uint32 tbl_idx)
{
uint32 i = 0;
AOTTableInstance *tbl_inst = (AOTTableInstance *)module_inst->tables.ptr;
while (i != tbl_idx) {
tbl_inst = aot_next_tbl_inst(tbl_inst);
++i;
}
return tbl_inst;
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _CONSTSTRDESC_H
#define _CONSTSTRDESC_H
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ConstStrDescription {
const char * str;
bool is_sys_symbol:1;
uint32 len:31;
uint32 hash;
struct ConstStrDescription * next;
} ConstStrDescription;
//#define CONST_STR_HASHMAP_KEY_HEAD_LEN (sizeof(void * ) + 2 * sizeof(uint32))
#define DEF_CONST_STRING(name, string) WAMR_CSP_##name,
#define DEF_CONST_STRING2(name) WAMR_CSP_##name,
enum WAMR_CONST_STRING_IDENT {
#include "wasm_symbols.h"
WAMR_CSP_SYMBOLS_end,
};
#undef DEF_CONST_STRING2
#undef DEF_CONST_STRING
#define DEF_CONST_STRING(name, string) string "\0"
#define DEF_CONST_STRING2(name) #name "\0"
static const char wasm_init_symbols[] = {
#include "wasm_symbols.h"
};
#undef DEF_CONST_STRING2
#undef DEF_CONST_STRING
#define CONST_STR_POOL_DESC(runtime, id) (&runtime->global_const_str_index_array[id])
#define CONST_STR_POOL_STR(runtime, id) (runtime->global_const_str_index_array[id].str)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -123,7 +123,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
is_import_func = ((AOTFunctionInstance *)func)->is_import_func;
is_import_func = ((AOTExportFunctionInstance *)func)->is_import_func;
}
#endif
@ -188,6 +188,19 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
return ret;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
bool
wasm_application_execute_program_main(WASMProgramCommon *program,
int32 argc, char *argv[])
{
WASMProgramInstance * program_inst = (WASMProgramInstance *)program;
if (!program_inst)
return false;
return wasm_application_execute_main((WASMModuleInstanceCommon*)program_inst->root_module_inst, argc, argv);
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
static WASMModuleInstance *
get_sub_module_inst(const WASMModuleInstance *parent_module_inst,
@ -295,9 +308,10 @@ resolve_function(const WASMModuleInstanceCommon *module_inst, const char *name)
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
AOTFunctionInstance *export_funcs =
(AOTFunctionInstance *)aot_inst->export_funcs.ptr;
for (i = 0; i < aot_inst->export_func_count; i++) {
AOTModule * aot_module = (AOTModule *)aot_inst->aot_module.ptr;
AOTExportFunctionInstance *export_funcs = (AOTExportFunctionInstance *)
aot_inst->export_funcs.ptr;
for (i = 0; i < aot_module->export_func_count; i++) {
if (!strcmp(export_funcs[i].func_name, function_name)) {
ret = &export_funcs[i];
break;
@ -681,3 +695,15 @@ fail:
os_printf("%s\n", exception);
return false;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
bool
wasm_application_execute_program_func(WASMProgramCommon *program,
const char *name, int32 argc, char *argv[])
{
WASMProgramInstance * program_inst = (WASMProgramInstance *)program;
if (!program_inst)
return false;
return wasm_application_execute_func((WASMModuleInstanceCommon*)program_inst->root_module_inst, name, argc, argv);
}
#endif

View File

@ -2001,7 +2001,7 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
}
for (i = 0; i != import_count; ++i) {
char *module_name_rt = NULL, *field_name_rt = NULL;
const char *module_name_rt = NULL, *field_name_rt = NULL;
if (i < import_func_count) {
wasm_functype_t *type = NULL;
@ -2011,8 +2011,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
if ((*module)->module_type == Wasm_Module_Bytecode) {
WASMImport *import =
MODULE_INTERP(module)->import_functions + i;
module_name_rt = import->u.names.module_name;
field_name_rt = import->u.names.field_name;
module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = (char*)import->u.names.field_name->str;
type_rt = import->u.function.func_type;
}
#endif
@ -2020,8 +2020,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
#if WASM_ENABLE_AOT != 0
if ((*module)->module_type == Wasm_Module_AoT) {
AOTImportFunc *import = MODULE_AOT(module)->import_funcs + i;
module_name_rt = import->module_name;
field_name_rt = import->func_name;
module_name_rt = import->module_name->str;
field_name_rt = import->func_name->str;
type_rt = import->func_type;
}
#endif
@ -2055,8 +2055,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
if ((*module)->module_type == Wasm_Module_Bytecode) {
WASMImport *import = MODULE_INTERP(module)->import_globals
+ (i - import_func_count);
module_name_rt = import->u.names.module_name;
field_name_rt = import->u.names.field_name;
module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = (char*)import->u.names.field_name->str;
val_type_rt = import->u.global.type;
mutability_rt = import->u.global.is_mutable;
}
@ -2064,10 +2064,10 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
#if WASM_ENABLE_AOT != 0
if ((*module)->module_type == Wasm_Module_AoT) {
AOTImportGlobal *import = MODULE_AOT(module)->import_globals
+ (i - import_func_count);
module_name_rt = import->module_name;
field_name_rt = import->global_name;
AOTImportGlobal *import =
MODULE_AOT(module)->import_globals + (i - import_func_count);
module_name_rt = import->module_name->str;
field_name_rt = import->global_name->str;
val_type_rt = import->type;
mutability_rt = import->is_mutable;
}
@ -2094,8 +2094,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
WASMImport *import =
MODULE_INTERP(module)->import_memories
+ (i - import_func_count - import_global_count);
module_name_rt = import->u.names.module_name;
field_name_rt = import->u.names.field_name;
module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = (char*)import->u.names.field_name->str;
min_page = import->u.memory.init_page_count;
max_page = import->u.memory.max_page_count;
}
@ -2144,8 +2144,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
MODULE_INTERP(module)->import_tables
+ (i - import_func_count - import_global_count
- import_memory_count);
module_name_rt = import->u.names.module_name;
field_name_rt = import->u.names.field_name;
module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = (char*)import->u.names.field_name->str;
elem_type_rt = import->u.table.elem_type;
min_size = import->u.table.init_size;
max_size = import->u.table.max_size;
@ -2745,7 +2745,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
if (export->kind == EXPORT_KIND_FUNC) {
if (export->index == func->func_idx_rt) {
func_comm_rt =
(AOTFunctionInstance *)inst_aot->export_funcs.ptr
(AOTExportFunctionInstance *)inst_aot->export_funcs.ptr
+ export_func_j;
((wasm_func_t *)func)->func_comm_rt = func_comm_rt;
break;
@ -2949,12 +2949,16 @@ interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt,
inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
//uint8 *data = global_interp->import_global_inst
// ? global_interp->import_module_inst->global_data
// + global_interp->import_global_inst->data_offset
// : inst_interp->global_data + global_interp->data_offset;
uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data
+ global_interp->import_global_inst->data_offset
: inst_interp->global_data + global_interp->data_offset;
? global_interp->import_global_inst->data
: global_interp->data;
#else
uint8 *data = inst_interp->global_data + global_interp->data_offset;
//uint8 *data = inst_interp->global_data + global_interp->data_offset;
uint8 * data = global_interp->data;
#endif
return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_interp,
@ -2968,12 +2972,16 @@ interp_global_get(const WASMModuleInstance *inst_interp, uint16 global_idx_rt,
WASMGlobalInstance *global_interp = inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
//uint8 *data = global_interp->import_global_inst
// ? global_interp->import_module_inst->global_data
// + global_interp->import_global_inst->data_offset
// : inst_interp->global_data + global_interp->data_offset;
uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data
+ global_interp->import_global_inst->data_offset
: inst_interp->global_data + global_interp->data_offset;
? global_interp->import_global_inst->data
: global_interp->data;
#else
uint8 *data = inst_interp->global_data + global_interp->data_offset;
//uint8 *data = inst_interp->global_data + global_interp->data_offset;
uint8 * data = global_interp->data;
#endif
return rt_val_to_wasm_val(data, val_type_rt, out);
@ -4357,11 +4365,12 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
#if WASM_ENABLE_AOT != 0
if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) {
uint32 export_cnt =
((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_tab_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_mem_count;
AOTModule * aot_module = (AOTModule*)((AOTModuleInstance *)instance->inst_comm_rt)->aot_module.ptr;
uint32 export_cnt = aot_module->export_count;
// ((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count
// + ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count
// + ((AOTModuleInstance *)instance->inst_comm_rt)->export_tab_count
// + ((AOTModuleInstance *)instance->inst_comm_rt)->export_mem_count;
INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized,
export_cnt);

View File

@ -144,26 +144,35 @@ wasm_runtime_free_internal(void *ptr)
}
}
int malloc_times = 0;
int realloc_times = 0;
int free_times = 0;
void *
wasm_runtime_malloc(unsigned int size)
{
bh_assert(size != 0);
if (size == 0) {
LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
/* At lease alloc 1 byte to avoid malloc failed */
size = 1;
}
malloc_times ++;
return wasm_runtime_malloc_internal(size);
}
void *
wasm_runtime_realloc(void *ptr, unsigned int size)
{
realloc_times ++;
return wasm_runtime_realloc_internal(ptr, size);
}
void
wasm_runtime_free(void *ptr)
{
free_times ++;
wasm_runtime_free_internal(ptr);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
#ifndef _WASM_MULTIMODULES_PROGRAM_H_
#define _WASM_MULTIMODULES_PROGRAM_H_
#include "../include/wasm_export.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ConstStrDescription ConstStrDescription;
#define TABLE_SPACE_BITS_LEN 10
#define TABLE_SPACE_SLOT_SIZE (1 << TABLE_SPACE_BITS_LEN)
#define TABLE_SPACE_FOR_INSTS_TOP_BOUNDARY 0x0fff0000u
#define MAX_INST_ID ((TABLE_SPACE_FOR_INSTS_TOP_BOUNDARY >> TABLE_SPACE_BITS_LEN) + 1)
#define BUILTIN_LIBC_INST_ID (MAX_INST_ID + 10u) //keep a gap
#define TABLE_SPACE_FOR_BUILTIN_LIBC ((BUILTIN_LIBC_INST_ID - 1) << 10)
typedef struct WASMModule WASMModule;
struct WASMModuleInstance;
typedef struct WASMModuleCommon WASMModuleCommon;
typedef struct WASMModuleInstanceCommon WASMModuleInstanceCommon;
typedef struct WASMModuleInstance WASMModuleInstance;
typedef struct AOTModuleInstance AOTModuleInstance;
typedef struct WASMTableInstance WASMTableInstance;
typedef struct WASMGlobalInstance WASMGlobalInstance;
typedef struct WASMFunctionInstance WASMFunctionInstance;
typedef struct AOTExportFunctionInstance AOTExportFunctionInstance;
typedef struct WASMExecEnv WASMExecEnv;
typedef struct AOTModule AOTModule;
typedef struct AOTImportFunc AOTImportFunc;
typedef struct WASMRuntime WASMRuntime;
typedef struct WASMProgramInstance WASMProgramInstance;
typedef struct WASMModuleInstanceHead WASMModuleInstanceHead;
typedef struct WASMExport WASMExport;
typedef struct WASMType WASMType;
typedef WASMType AOTFuncType;
typedef struct wasm_runtime_config_ {
bool need_load_dependencies;
bool auto_update_extension;
bool launch_AS_module;
} wasm_runtime_config;
struct WASMRuntime {
wasm_runtime_config config;
// save all const strings and hash values.
HashMap * global_const_str_pool;
// save all const strings pointers based on string index,
// can compare pointers instead of content.
ConstStrDescription * global_const_str_index_array;
uint32 csp_size;
uint32 csp_strings_count;
uint32 csp_free_index;
HashMap * all_loaded_modules;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMProgramInstance * cur_loading_program;
#endif
module_reader reader;
module_destroyer destroyer;
};
#if WASM_ENABLE_DYNAMIC_LINKING != 0
typedef enum {
EARLY_BINDING = 0,
LAZY_BINDING
} WASM_BINDING_MODE;
typedef enum {
FROM_BUILTIN_LIBC = 0, // when root module and dependencies modules independently link against builtin libc.
FROM_ROOT // import malloc/free/realloc from root module exports.
} WASM_IMPORT_MEMOP_MODE;
typedef struct wasm_program_config_ {
WASM_BINDING_MODE binding_mode;
WASM_IMPORT_MEMOP_MODE import_memop_mode;
bool use_tbl_as_cache; // allocate extra table space as resolve cache to store exports resolving result.
bool root_is_AS_module;
bool use_resolve_cache;
} wasm_program_config;
#define BINDING_MODE_MASK 0x1 // 0 is lazy_binding
#define MEM_ALLOCATOR_MASK (0x1 << 1) // 0 is from builtin libc, 1 is from root module.
#define USE_TBL_AS_CACHE_MASK (0x1 << 2)
#define ROOT_IS_AS_MODULE_MASK (0x1 << 3)
#define USE_RESOLVE_CACHE_MASK (0x1 << 4)
#define PROGRAM_RESOLVING_CACHE_LINE_LEN 2
#define PROGRAM_RESOLVING_CACHE_LINE_COUNT 16
typedef struct wasm_resolving_cache_entry_ {
int32 index;
void * func_inst;
#if WASM_ENABLE_AOT != 0
void * module_inst; // interp doesn't need it, we saved the module inst in wasmfunctioninstance.
#endif
} wasm_resolving_cache_entry;
struct WASMProgramInstance {
/* explicit dependency modules, means loading by dlopen */
/* implicit dependency modules, means these modules in dylink section
they will be recorded in WASMModule */
WASMRuntime * runtime;
wasm_program_config config;
/* current program's root module instance, used to allocate init
memory space for other modules */
WASMModuleInstanceCommon * root_module_inst;
// bh_list loading_modules_list;
/* all dependency modules of current instance, avoid loading same module at runtime */
/* they includes implicit modules comes from root module and explicit modules added
at runtime by dlopen() */
HashMap * global_modules_inst_name_hmap;
wasm_resolving_cache_entry * resolving_cache;
// alloc module instance id and table space according to instance id.
HashMap * global_modules_inst_id_hmap;
uint32 next_free_inst_id;
// here, use a function array to simulate a internal libc module.
// a little bit ugly, seems we should create a real libc wasm module internally.
#if WASM_ENABLE_LIBC_BUILTIN != 0
void ** builtin_libc_funcs;
uint32 builtin_libc_funcs_count;
uint32 builtin_libc_funcs_size;
/* memory allocated in user linear space, it's wasm linear addr, uint32 */
uint32 ctype_tolower_loc_space;
#endif
bool clean_all;
WASMModuleInstanceCommon * exception_inst;
char *error_buf;
uint32 error_buf_size;
};
#endif
void
wasm_runtime_set_module_reader(const module_reader reader_cb,
const module_destroyer destroyer_cb);
module_reader
wasm_runtime_get_module_reader();
module_destroyer
wasm_runtime_get_module_destroyer();
WASMModuleCommon *
wasm_runtime_get_module_by_name(WASMRuntime * runtime, const ConstStrDescription * module_name);
bool
wasm_runtime_is_system_symbol(WASMRuntime * runtime, const ConstStrDescription * key);
bool
wasm_runtime_is_memop_symbol(WASMRuntime * runtime, const ConstStrDescription * key);
uint32
wasm_runtime_get_syssymbol_id(WASMRuntime * runtime, const ConstStrDescription * key);
const ConstStrDescription *
wasm_runtime_records_const_filename_string(WASMRuntime * runtime,
const char * str, const uint32 len,
char* error_buf, uint32 error_buf_size);
const ConstStrDescription *
wasm_runtime_records_const_string(WASMRuntime * runtime,
const char * str, const uint32 len,
char* error_buf, uint32 error_buf_size);
const ConstStrDescription *
upgrade_module_extension(const WASMRuntime *runtime,
const ConstStrDescription * key_module_name,
const package_type_t expected_module_type,
char * error_buf,
uint32 error_buf_size);
WASMRuntime *
wasm_runtime_get_runtime();
bool
wasm_runtime_runtime_init(bool standalone, bool auto_ext_name);
void
wasm_runtime_runtime_destroy();
WASMModuleInstanceCommon *
wasm_program_get_root_module_from_inst(const WASMModuleInstanceCommon * module_inst);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
#if WASM_ENABLE_LIBC_BUILTIN != 0
uint32
wasm_program_get_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst);
void
wasm_program_set_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst, uint32 addr);
#endif
WASMProgramInstance *
wasm_runtime_create_program_internal(
char * error_buf, uint32 error_buf_size,
uint32 dlopen_mode);
void
wasm_runtime_destroy_program_internal(WASMProgramInstance * program);
bool
wasm_program_is_root_module(const WASMModuleInstanceCommon * module_inst);
WASMModuleInstanceCommon *
wasm_program_get_root_module(const WASMProgramInstance * program);
WASMModuleInstanceCommon *
wasm_program_get_root_module_from_env(const wasm_exec_env_t env);
void
wasm_program_set_root_module(WASMProgramInstance * program, const WASMModuleInstanceCommon * module_inst);
void
wasm_program_remove_module_inst_from_name_hmap(WASMProgramInstance * program, WASMModuleInstance * module_inst);
void
wasm_program_cache_resolve_result(WASMProgramInstance * program, int32 id, void * result_func, void * module_inst);
void *
wasm_program_lookup_cached_resolving_func(WASMProgramInstance * program, int32 id);
void
wasm_program_invalidate_cached_wasm_func(WASMProgramInstance * program, wasm_module_inst_t module_inst);
uint32
wasm_program_alloc_module_instance_id(WASMProgramInstance * program, WASMModuleInstanceCommon * module_inst);
void
wasm_program_free_module_instance_id(WASMProgramInstance * program, uint32 inst_id);
WASMModuleInstanceCommon *
wasm_program_get_module_inst_by_id(WASMProgramInstance * program, uint32 inst_idx);
WASMModuleInstanceCommon *
wasm_program_get_module_inst_by_name(WASMProgramInstance * program, const ConstStrDescription * module_name);
WASMModuleInstanceCommon *
wasm_program_get_dep_module_inst_by_name(WASMModuleInstanceCommon * caller_module_inst, const ConstStrDescription * module_name);
bool
wasm_program_insert_module_inst_by_name(WASMProgramInstance * program,
WASMModuleInstanceCommon * module_inst,
const ConstStrDescription * module_name);
WASMModuleInstanceCommon *
wasm_program_instantiate_dependencies(WASMRuntime * runtime,
WASMProgramInstance * program_inst,
WASMModuleInstanceCommon * caller_module_inst,
WASMModuleCommon * module);
void
wasm_program_close_dependencies(wasm_module_inst_t module_inst,
uint32 inst_id);
WASMModuleInstanceCommon *
wasm_program_open_dependencies_general(WASMRuntime * runtime,
WASMProgramInstance * program_inst,
WASMModuleInstanceCommon * caller_module_inst,
const char * path);
uint32
wasm_program_open_dependencies(wasm_module_inst_t module_inst,
const char * path);
uint32
wasm_program_lookup_symbol_from_module(wasm_module_inst_t caller_module,
uint32 module_handle, const char * symbol);
bool
wasm_program_resolve_op_call(WASMProgramInstance * program,
WASMModuleInstance * caller_module_inst,
WASMModuleInstance ** p_callee_module_inst,
WASMFunctionInstance ** p_call_func);
bool
wasm_program_resolve_aot_function(WASMProgramInstance * program,
AOTModuleInstance * caller_module_inst,
AOTModuleInstance ** p_callee_module_inst,
uint32 import_func_id);
uint32
wasm_program_alloc_table_space_by_size(uint32 inst_id,
uint32 needed_size);
uint32
wasm_program_alloc_table_space_by_table(WASMModuleInstance * module_inst,
WASMTableInstance * table);
bool
wasm_program_link_sp_wasm_globals(WASMProgramInstance * program,
WASMGlobalInstance * global,
const ConstStrDescription * field_name);
bool
wasm_program_link_got_globals(WASMProgramInstance * program,
WASMModuleInstance * module_inst,
WASMGlobalInstance * global,
const ConstStrDescription * field_name);
#if WASM_ENABLE_AOT != 0
bool
wasm_program_link_sp_aot_globals(WASMProgramInstance * program,
uint8 * p_global_data,
const ConstStrDescription * global_name);
bool
wasm_program_link_aot_got_globals(WASMProgramInstance * program,
AOTModuleInstance * module_inst,
uint8 * p_global_data,
const ConstStrDescription * field_name);
#endif
bool
wasm_program_resolve_op_call_indirect(WASMProgramInstance * program,
WASMModuleInstance * module_inst,
uint32 tbl_idx,
int32 tbl_slot_id,
WASMType * func_type,
WASMModuleInstance ** p_callee_module_inst,
WASMFunctionInstance ** p_call_func);
#if WASM_ENABLE_AOT != 0
bool
wasm_program_resolve_aot_op_call_indirect(WASMExecEnv *exec_env,
WASMProgramInstance * program,
AOTModuleInstance * module_inst,
uint32 tbl_idx,
int32 table_elem_idx,
uint32 expected_type_idx,
AOTFuncType * expected_type,
AOTModuleInstance ** p_callee_module_inst,
AOTModule ** p_callee_module,
uint32 * p_call_func_index,
AOTImportFunc ** p_import_func);
#endif
bool
wasm_program_validate_mode_compatiability(WASMProgramInstance * program);
WASMModuleCommon *
load_implicit_dependency_module(const WASMModuleCommon *parent_module,
const ConstStrDescription * key,
char * error_buf,
uint32 error_buf_size);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -20,7 +20,36 @@
#include <sys/time.h>
#endif
static NativeSymbolsList g_native_symbols_list = NULL;
static NativeSymbolsVec g_native_symbols_vec = NULL;
static uint32 g_native_libs_count = 0;
static uint32 g_native_libs_size = 0;
enum {
#if WASM_ENABLE_LIBC_BUILTIN != 0
ID_LIBC_BUILTIN = 0,
#endif
#if WASM_ENABLE_SPEC_TEST
ID_SPECTEST,
#endif
#if WASM_ENABLE_LIBC_WASI != 0
ID_LIBC_WASI_UNSTABLE,
ID_LIBC_WASI_PREVIEW1,
#endif
#if WASM_ENABLE_BASE_LIB != 0
ID_BASE_LIB,
#endif
#if WASM_ENABLE_APP_FRAMEWORK != 0
ID_APP_FRAME,
#endif
#if WASM_ENABLE_LIB_PTHREAD != 0
ID_PTHREAD,
#endif
#if WASM_ENABLE_LIBC_EMCC != 0
ID_LIBC_EMCC,
#endif
ID_USER,
NODE_COUNT
};
uint32
get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
@ -53,7 +82,7 @@ get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis);
uint32
get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
static bool
bool
check_symbol_signature(const WASMType *type, const char *signature)
{
const char *p = signature, *p_end;
@ -121,7 +150,7 @@ check_symbol_signature(const WASMType *type, const char *signature)
return true;
}
/*
#if ENABLE_QUICKSORT == 0
static void
sort_symbol_ptr(NativeSymbol *native_symbols, uint32 n_native_symbols)
@ -188,12 +217,12 @@ quick_sort_symbols(NativeSymbol *native_symbols, int left, int right)
quick_sort_symbols(native_symbols, pin_left, left - 1);
quick_sort_symbols(native_symbols, left + 1, pin_right);
}
#endif /* end of ENABLE_QUICKSORT */
#endif
*/
static void *
lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
const char *symbol, const char **p_signature, void **p_attachment)
{
const ConstStrDescription *symbol, const char **p_signature, void **p_attachment)
{/*
int low = 0, mid, ret;
int high = (int32)n_native_symbols - 1;
@ -210,19 +239,78 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
else
low = mid + 1;
}
*/
uint32 i = 0;
for (i = 0; i < n_native_symbols; i ++) {
NativeSymbol * native_symbol = &native_symbols[i];
if (native_symbol->u.symbol == symbol) {
*p_signature = native_symbol->signature;
*p_attachment = native_symbol->attachment;
return native_symbol->func_ptr;
}
}
return NULL;
}
void *
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
wasm_native_resolve_symbol(const ConstStrDescription *module_name,
const ConstStrDescription ** p_field_name,
const WASMType *func_type, const char **p_signature,
void **p_attachment, bool *p_call_conv_raw)
{
NativeSymbolsNode *node, *node_next;
WASMRuntime * runtime = wasm_runtime_get_runtime();
NativeSymbolsNode *node = NULL;
const char *signature = NULL;
const ConstStrDescription * field_name = *p_field_name;
void *func_ptr = NULL, *attachment;
uint32 field_id =0, first_sym_id = 0, symbol_index = 0;
bool pass_check = false;
if (wasm_runtime_is_system_symbol(runtime, module_name) &&
wasm_runtime_is_system_symbol(runtime, field_name)) {
for (uint32 i = 0; i < ID_USER; i ++) {
node = &g_native_symbols_vec[i];
if (node->module_name == module_name) {
field_id = wasm_runtime_get_syssymbol_id(runtime, field_name);
first_sym_id = wasm_runtime_get_syssymbol_id(runtime, node->native_symbols[0].u.symbol);
if (field_id < first_sym_id + node->n_native_symbols) {
symbol_index = field_id - first_sym_id;
func_ptr = node->native_symbols[symbol_index].func_ptr;
signature = node->native_symbols[symbol_index].signature;
attachment = node->native_symbols[symbol_index].attachment;
break;
}
}
}
} else {
for (uint32 i = ID_USER; i < g_native_libs_count; i ++) {
node = &g_native_symbols_vec[i];
if (node->module_name == module_name) {
func_ptr =
lookup_symbol(node->native_symbols, node->n_native_symbols,
field_name, &signature, &attachment);
if (func_ptr) {
break;
}
if (field_name->str[0] == '_') {
const ConstStrDescription * new_field_name =
wasm_runtime_records_const_string(runtime, &field_name->str[1], field_name->len - 1, NULL, 0);
func_ptr =
lookup_symbol(node->native_symbols, node->n_native_symbols,
new_field_name, &signature, &attachment);
if (func_ptr)
break;
}
}
}
}
#if 0
node = g_native_symbols_list;
while (node) {
node_next = node->next;
@ -238,11 +326,24 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
}
node = node_next;
}
#endif
if (func_ptr) {
if (signature && signature[0] != '\0') {
/* signature is not empty, check its format */
if (!check_symbol_signature(func_type, signature)) {
// hotfix abort() if launching AS module
if (symbol_index && node->native_symbols[++symbol_index].u.symbol == field_name) {
signature = node->native_symbols[symbol_index].signature;
if (check_symbol_signature(func_type, signature)) {
*p_signature = signature;
func_ptr = node->native_symbols[symbol_index].func_ptr;
attachment = node->native_symbols[symbol_index].attachment;
pass_check = true;
}
}
if (!pass_check) {
#if WASM_ENABLE_WAMR_COMPILER == 0
/* Output warning except running aot compiler */
LOG_WARNING("failed to check signature '%s' and resolve "
@ -251,6 +352,7 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
#endif
return NULL;
}
}
else
/* Save signature for runtime to do pointer check and
address conversion */
@ -271,28 +373,53 @@ static bool
register_natives(const char *module_name, NativeSymbol *native_symbols,
uint32 n_native_symbols, bool call_conv_raw)
{
NativeSymbolsNode *node;
WASMRuntime * runtime = wasm_runtime_get_runtime();
/*
#if ENABLE_SORT_DEBUG != 0
struct timeval start;
struct timeval end;
unsigned long timer;
#endif
if (!(node = wasm_runtime_malloc(sizeof(NativeSymbolsNode))))
*/
if (!runtime)
return false;
#if WASM_ENABLE_MEMORY_TRACING != 0
os_printf("Register native, size: %u\n", sizeof(NativeSymbolsNode));
#endif
node->module_name = module_name;
node->native_symbols = native_symbols;
node->n_native_symbols = n_native_symbols;
node->call_conv_raw = call_conv_raw;
if ((g_native_libs_count + 1) > g_native_libs_size) {
g_native_symbols_vec = wasm_runtime_realloc(
g_native_symbols_vec, (g_native_libs_size + 2) * sizeof(NativeSymbolsNode));
if (!g_native_symbols_vec) {
return false;
}
/* Add to list head */
node->next = g_native_symbols_list;
g_native_symbols_list = node;
g_native_libs_size += 2;
bh_assert((g_native_libs_count + 2) == g_native_libs_size);
}
const ConstStrDescription * csp_module_name =
wasm_runtime_records_const_string(runtime, module_name, strlen(module_name), NULL, 0);
g_native_symbols_vec[g_native_libs_count].module_name = csp_module_name;
g_native_symbols_vec[g_native_libs_count].native_symbols = NULL;
g_native_symbols_vec[g_native_libs_count].n_native_symbols = n_native_symbols;
g_native_symbols_vec[g_native_libs_count].call_conv_raw = call_conv_raw;
NativeSymbol * csp_native_symbols = (NativeSymbol*)wasm_runtime_malloc(sizeof(NativeSymbol) * n_native_symbols);
if (!csp_native_symbols) {
return false;
}
for (uint32 i = 0; i < n_native_symbols; i++) {
memcpy(&csp_native_symbols[i], &native_symbols[i], sizeof(NativeSymbol));
csp_native_symbols[i].u.symbol =
wasm_runtime_records_const_string(runtime, native_symbols[i].u.symbol_str,
strlen(native_symbols[i].u.symbol_str), NULL, 0);
}
g_native_symbols_vec[g_native_libs_count].native_symbols = csp_native_symbols;
g_native_libs_count ++;
/*
#if ENABLE_SORT_DEBUG != 0
gettimeofday(&start, NULL);
#endif
@ -310,6 +437,7 @@ register_natives(const char *module_name, NativeSymbol *native_symbols,
LOG_ERROR("module_name: %s, nums: %d, sorted used: %ld us", module_name,
n_native_symbols, timer);
#endif
*/
return true;
}
@ -334,46 +462,94 @@ wasm_native_register_natives_raw(const char *module_name,
bool
wasm_native_init()
{
WASMRuntime * runtime = wasm_runtime_get_runtime();
NativeSymbol *native_symbols;
uint32 n_native_symbols;
uint32 n_native_symbols = 0;
uint32 n_native_nodes = g_native_libs_size = NODE_COUNT;
g_native_libs_count = NODE_COUNT - 1;
if (!runtime)
return false;
if (n_native_nodes) {
g_native_symbols_vec = (NativeSymbolsNode*)wasm_runtime_malloc(
sizeof(NativeSymbolsNode) * n_native_nodes);
if (!g_native_symbols_vec)
return false;
memset(g_native_symbols_vec, 0, sizeof(NativeSymbolsNode) * n_native_nodes);
}
#if WASM_ENABLE_LIBC_BUILTIN != 0
n_native_symbols = get_libc_builtin_export_apis(&native_symbols);
if (!wasm_native_register_natives("env", native_symbols, n_native_symbols))
return false;
#endif /* WASM_ENABLE_LIBC_BUILTIN */
//if (!wasm_native_register_natives(CONST_STR_POOL_DESC(WAMR_CSP_env), native_symbols, n_native_symbols))
// return false;
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
#if WASM_ENABLE_SPEC_TEST
g_native_symbols_vec[ID_LIBC_BUILTIN].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
g_native_symbols_vec[ID_LIBC_BUILTIN].native_symbols = native_symbols;
g_native_symbols_vec[ID_LIBC_BUILTIN].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_LIBC_BUILTIN].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_SPEC_TEST != 0
n_native_symbols = get_spectest_export_apis(&native_symbols);
if (!wasm_native_register_natives("spectest", native_symbols,
n_native_symbols))
return false;
#endif /* WASM_ENABLE_SPEC_TEST */
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_SPECTEST].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_spectest);
g_native_symbols_vec[ID_SPECTEST].native_symbols = native_symbols;
g_native_symbols_vec[ID_SPECTEST].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_SPECTEST].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_LIBC_WASI != 0
n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
if (!wasm_native_register_natives("wasi_unstable", native_symbols,
n_native_symbols))
return false;
if (!wasm_native_register_natives("wasi_snapshot_preview1", native_symbols,
n_native_symbols))
return false;
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_LIBC_WASI_UNSTABLE].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_unstable);
g_native_symbols_vec[ID_LIBC_WASI_UNSTABLE].native_symbols = native_symbols;
g_native_symbols_vec[ID_LIBC_WASI_UNSTABLE].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_LIBC_WASI_UNSTABLE].call_conv_raw = false;
g_native_symbols_vec[ID_LIBC_WASI_PREVIEW1].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_snapshot_preview1);
g_native_symbols_vec[ID_LIBC_WASI_PREVIEW1].native_symbols = native_symbols;
g_native_symbols_vec[ID_LIBC_WASI_PREVIEW1].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_LIBC_WASI_PREVIEW1].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_BASE_LIB != 0
n_native_symbols = get_base_lib_export_apis(&native_symbols);
if (n_native_symbols > 0
&& !wasm_native_register_natives("env", native_symbols,
n_native_symbols))
return false;
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_BASE_LIB].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
g_native_symbols_vec[ID_BASE_LIB].native_symbols = native_symbols;
g_native_symbols_vec[ID_BASE_LIB].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_BASE_LIB].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_APP_FRAMEWORK != 0
n_native_symbols = get_ext_lib_export_apis(&native_symbols);
if (n_native_symbols > 0
&& !wasm_native_register_natives("env", native_symbols,
n_native_symbols))
return false;
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_APP_FRAME].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
g_native_symbols_vec[ID_APP_FRAME].native_symbols = native_symbols;
g_native_symbols_vec[ID_APP_FRAME].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_APP_FRAME].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_LIB_PTHREAD != 0
@ -381,19 +557,29 @@ wasm_native_init()
return false;
n_native_symbols = get_lib_pthread_export_apis(&native_symbols);
if (n_native_symbols > 0
&& !wasm_native_register_natives("env", native_symbols,
n_native_symbols))
return false;
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_PTHREAD].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
g_native_symbols_vec[ID_PTHREAD].native_symbols = native_symbols;
g_native_symbols_vec[ID_PTHREAD].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_PTHREAD].call_conv_raw = false;
}
#endif
#if WASM_ENABLE_LIBC_EMCC != 0
n_native_symbols = get_libc_emcc_export_apis(&native_symbols);
if (n_native_symbols > 0
&& !wasm_native_register_natives("env", native_symbols,
n_native_symbols))
return false;
#endif /* WASM_ENABLE_LIBC_EMCC */
if (n_native_symbols) {
for (uint32 i = 0; i < n_native_symbols; i ++)
native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
g_native_symbols_vec[ID_LIBC_EMCC].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
g_native_symbols_vec[ID_LIBC_EMCC].native_symbols = native_symbols;
g_native_symbols_vec[ID_LIBC_EMCC].n_native_symbols = n_native_symbols;
g_native_symbols_vec[ID_LIBC_EMCC].call_conv_raw = false;
}
#endif
return true;
}
@ -401,18 +587,17 @@ wasm_native_init()
void
wasm_native_destroy()
{
NativeSymbolsNode *node, *node_next;
#if WASM_ENABLE_LIB_PTHREAD != 0
lib_pthread_destroy();
#endif
node = g_native_symbols_list;
while (node) {
node_next = node->next;
wasm_runtime_free(node);
node = node_next;
for (uint32 i = ID_USER; i < g_native_libs_count; i ++) {
if (g_native_symbols_vec[i].native_symbols)
wasm_runtime_free(g_native_symbols_vec[i].native_symbols);
}
g_native_symbols_list = NULL;
if (g_native_symbols_vec)
wasm_runtime_free(g_native_symbols_vec);
g_native_symbols_vec = NULL;
}

View File

@ -15,12 +15,12 @@ extern "C" {
#endif
typedef struct NativeSymbolsNode {
struct NativeSymbolsNode *next;
const char *module_name;
//struct NativeSymbolsNode *next;
const ConstStrDescription *module_name;
NativeSymbol *native_symbols;
uint32 n_native_symbols;
bool call_conv_raw;
} NativeSymbolsNode, *NativeSymbolsList;
} NativeSymbolsNode, *NativeSymbolsVec;
/**
* Lookup global variable of a given import global
@ -50,7 +50,8 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
* @return the native function pointer if success, NULL otherwise
*/
void *
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
wasm_native_resolve_symbol(const ConstStrDescription *module_name,
const ConstStrDescription ** p_field_name,
const WASMType *func_type, const char **p_signature,
void **p_attachment, bool *p_call_conv_raw);
@ -70,6 +71,9 @@ wasm_native_init();
void
wasm_native_destroy();
bool
check_symbol_signature(const WASMType *type, const char *signature);
#ifdef __cplusplus
}
#endif

View File

@ -99,13 +99,9 @@ wasm_runtime_env_init()
if (bh_platform_init() != 0)
return false;
if (wasm_native_init() == false) {
goto fail1;
}
#if WASM_ENABLE_MULTI_MODULE
if (BHT_OK != os_mutex_init(&registered_module_list_lock)) {
goto fail2;
goto fail1;
}
if (BHT_OK != os_mutex_init(&loading_module_list_lock)) {
@ -171,12 +167,9 @@ fail4:
os_mutex_destroy(&loading_module_list_lock);
fail3:
os_mutex_destroy(&registered_module_list_lock);
fail2:
#endif
wasm_native_destroy();
fail1:
bh_platform_destroy();
#endif
return false;
}
@ -200,6 +193,16 @@ wasm_runtime_init()
return false;
}
if (!wasm_runtime_runtime_init(true, true)) {
wasm_runtime_destroy();
return false;
}
if (!wasm_native_init()) {
wasm_runtime_destroy();
return false;
}
return true;
}
@ -240,6 +243,9 @@ wasm_runtime_destroy()
#endif
wasm_native_destroy();
wasm_runtime_runtime_destroy();
bh_platform_destroy();
wasm_runtime_memory_destroy();
@ -253,7 +259,13 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
return false;
if (!wasm_runtime_env_init()) {
wasm_runtime_memory_destroy();
wasm_runtime_destroy();
return false;
}
if (!wasm_runtime_runtime_init(init_args->standalone,
init_args->auto_ext_name)) {
wasm_runtime_destroy();
return false;
}
@ -267,6 +279,11 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
}
#endif
if (!wasm_native_init()) {
wasm_runtime_destroy();
return false;
}
if (init_args->n_native_symbols > 0
&& !wasm_runtime_register_natives(init_args->native_module_name,
init_args->native_symbols,
@ -294,29 +311,8 @@ get_package_type(const uint8 *buf, uint32 size)
return Package_Type_Unknown;
}
#if WASM_ENABLE_MULTI_MODULE != 0
static module_reader reader;
static module_destroyer destroyer;
void
wasm_runtime_set_module_reader(const module_reader reader_cb,
const module_destroyer destroyer_cb)
{
reader = reader_cb;
destroyer = destroyer_cb;
}
module_reader
wasm_runtime_get_module_reader()
{
return reader;
}
module_destroyer
wasm_runtime_get_module_destroyer()
{
return destroyer;
}
static WASMRegisteredModule *
wasm_runtime_find_module_registered_by_reference(WASMModuleCommon *module)
{
@ -491,12 +487,12 @@ wasm_runtime_destroy_registered_module_list()
}
/* destroy the file buffer */
if (destroyer && reg_module->orig_file_buf) {
destroyer(reg_module->orig_file_buf,
reg_module->orig_file_buf_size);
reg_module->orig_file_buf = NULL;
reg_module->orig_file_buf_size = 0;
}
//if (destroyer && reg_module->orig_file_buf) {
// destroyer(reg_module->orig_file_buf,
// reg_module->orig_file_buf_size);
// reg_module->orig_file_buf = NULL;
// reg_module->orig_file_buf_size = 0;
//}
wasm_runtime_free(reg_module);
reg_module = next_reg_module;
@ -600,6 +596,18 @@ wasm_runtime_is_built_in_module(const char *module_name)
|| !strcmp("", module_name));
}
bool
wasm_runtime_is_built_in_module_new(WASMRuntime * runtime, const ConstStrDescription *module_name)
{
return (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env)
|| module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_unstable)
|| module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_snapshot_preview1)
#if WASM_ENABLE_SPEC_TEST != 0
|| module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_spectest)
#endif
|| module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_null));
}
#if WASM_ENABLE_THREAD_MGR != 0
bool
wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset,
@ -666,6 +674,195 @@ register_module_with_null_name(WASMModuleCommon *module_common, char *error_buf,
#endif
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
bool
read_expected_target_module(module_reader reader, module_destroyer destroyer,
const char *module_name, const uint32 name_len,
const package_type_t expected_module_type,
uint8 ** pbuffer, uint32 * p_buffer_size)
{
PackageType module_type;
char * new_module_name = NULL;
const char * postfix = NULL;
uint32 offset = 0, new_name_len = 0;
// read file according to original file name
if (reader(module_name, pbuffer, p_buffer_size)) {
module_type = get_package_type(*pbuffer, *p_buffer_size);
if (module_type == expected_module_type) {
return true;
}
destroyer(*pbuffer, *p_buffer_size);
// wouldn't change the extension for user when explicit open a module.
return false;
// change extension name, try again
offset = name_len;
postfix = strrchr(module_name, '.');
if (postfix) {
offset = postfix - module_name;
}
new_name_len = offset + sizeof(".wasm") + 1;
new_module_name = (char*)wasm_runtime_malloc(new_name_len);
memset(new_module_name, 0, new_name_len);
memcpy(new_module_name, module_name, offset);
if (expected_module_type == Wasm_Module_Bytecode)
strncat(new_module_name, ".wasm", new_name_len);
else
strncat(new_module_name, ".aot", new_name_len);
if (reader(new_module_name, pbuffer, p_buffer_size)) {
wasm_runtime_free(new_module_name);
return true;
}
destroyer(*pbuffer, *p_buffer_size);
wasm_runtime_free(new_module_name);
return false;
}
return false;
}
WASMModuleCommon *
load_dependency_module_internal(module_reader reader, module_destroyer destroyer,
const char *sub_module_name, const uint32 name_len,
const package_type_t expected_module_type,
char *error_buf,
uint32 error_buf_size)
{
uint8 *buffer = NULL;
uint32 buffer_size = 0;
WASMModuleCommon * new_module = NULL;
PackageType module_type;
if (!read_expected_target_module(reader, destroyer,
sub_module_name, name_len, expected_module_type, &buffer, &buffer_size)) {
return NULL;
}
module_type = get_package_type(buffer, buffer_size);
if (module_type == Wasm_Module_Bytecode) {
new_module =
(WASMModuleCommon*)wasm_load(buffer, buffer_size, error_buf, error_buf_size);
} else {
#if WASM_ENABLE_AOT != 0
new_module =
(WASMModuleCommon*)aot_load_from_aot_file(buffer, buffer_size, error_buf, error_buf_size);
#endif
}
if (!new_module) {
/* others will be destroyed in runtime_destroy() */
destroyer(buffer, buffer_size);
return NULL;
}
if (module_type == Wasm_Module_Bytecode) {
((WASMModule*)new_module)->file_buf = buffer;
} else {
#if WASM_ENABLE_AOT != 0
((AOTModule*)new_module)->file_buf = buffer;
#endif
}
return new_module;
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal2(WASMProgramCommon * program,
WASMModuleCommon *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size);
WASMProgramCommon *
wasm_runtime_create_program(WASMModuleCommon* module, uint32 stack_size,
uint32 heap_size, uint32 dlopen_mode,
char * error_buf, uint32 error_buf_size)
{
WASMModuleInstanceCommon * root_module_inst = NULL;
WASMProgramInstance * program = NULL;
if (!module)
return NULL;
program = wasm_runtime_create_program_internal(error_buf, error_buf_size,
dlopen_mode);
if (!program) {
return NULL;
}
root_module_inst = wasm_runtime_instantiate_internal2(
(WASMProgramCommon *)program, module, false, stack_size, heap_size, NULL, 0);
if (!root_module_inst) {
wasm_runtime_destroy_program_internal(program);
return NULL;
}
wasm_program_set_root_module(program, root_module_inst);
wasm_program_validate_mode_compatiability(program);
return (WASMProgramCommon *)program;
}
void
wasm_runtime_destroy_program(WASMProgramCommon* program)
{
if (!program)
return;
wasm_runtime_destroy_program_internal((WASMProgramInstance*)program);
}
#endif
WASMModuleCommon *
wasm_runtime_load2(const char * name,
const uint8 *buf, uint32 size,
char *error_buf, uint32 error_buf_size)
{
WASMModuleCommon *module_common = NULL;
WASMRuntime * runtime = wasm_runtime_get_runtime();
const ConstStrDescription * key = NULL;
if (!name || !buf)
return NULL;
key = wasm_runtime_records_const_string(wasm_runtime_get_runtime(),
name, strlen(name),
error_buf, error_buf_size);
if (!key)
return NULL;
module_common = wasm_runtime_load(buf, size, error_buf, error_buf_size);
if (!module_common)
return NULL;
if (module_common->module_type == Wasm_Module_Bytecode)
((WASMModule*)module_common)->module_name = (ConstStrDescription*)key;
else {
#if WASM_ENABLE_AOT != 0
((AOTModule*)module_common)->module_name = (ConstStrDescription*)key;
#endif
}
if (!runtime->all_loaded_modules)
return module_common;
if (!bh_hash_map_insert_with_dup(runtime->all_loaded_modules,
(void*)key, (void*)module_common)) {
wasm_runtime_unload(module_common);
return NULL;
}
return module_common;
}
WASMModuleCommon *
wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
uint32 error_buf_size)
@ -741,6 +938,28 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
return NULL;
}
void
wasm_runtime_unload2(WASMModuleCommon *module)
{
WASMModuleCommon * old_module = NULL;
const ConstStrDescription * key = NULL;
ConstStrDescription * old_key = NULL;
WASMRuntime * runtime = wasm_runtime_get_runtime();
if (runtime->all_loaded_modules) {
key = ((WASMModule*)module)->module_name;
bh_hash_map_remove(runtime->all_loaded_modules,
(void*)key,
(void*)&old_key,
(void*)&old_module);
}
// wasm_runtime_free(old_key);
wasm_runtime_unload(module);
}
void
wasm_runtime_unload(WASMModuleCommon *module)
{
@ -768,21 +987,24 @@ wasm_runtime_unload(WASMModuleCommon *module)
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
wasm_runtime_instantiate_internal2(WASMProgramCommon * program,
WASMModuleCommon *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
return (WASMModuleInstanceCommon *)wasm_instantiate(
(WASMModule *)module, is_sub_inst, stack_size, heap_size, error_buf,
error_buf_size);
return (WASMModuleInstanceCommon*)
wasm_instantiate((WASMProgramInstance*)program, (WASMModule*)module, is_sub_inst,
stack_size, heap_size,
error_buf, error_buf_size);
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
return (WASMModuleInstanceCommon *)aot_instantiate(
(AOTModule *)module, is_sub_inst, stack_size, heap_size, error_buf,
error_buf_size);
return (WASMModuleInstanceCommon*)
aot_instantiate((WASMProgramInstance*)program, (AOTModule*)module, is_sub_inst,
stack_size, heap_size,
error_buf, error_buf_size);
#endif
set_error_buf(error_buf, error_buf_size,
"Instantiate module failed, invalid module type");
@ -790,12 +1012,23 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
uint32 heap_size, char *error_buf,
uint32 error_buf_size)
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{
return wasm_runtime_instantiate_internal(
module, false, stack_size, heap_size, error_buf, error_buf_size);
return wasm_runtime_instantiate_internal2(NULL, module, is_sub_inst,
stack_size, heap_size,
error_buf, error_buf_size);
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{
return wasm_runtime_instantiate_internal(module, false,
stack_size, heap_size,
error_buf, error_buf_size);
}
void
@ -1053,6 +1286,16 @@ wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
return wasm_exec_env_get_module_inst(exec_env);
}
WASMModuleInstanceCommon *
wasm_runtime_get_root_module_inst(WASMExecEnv *exec_env)
{
WASMModuleInstanceCommon * module_inst = wasm_exec_env_get_module_inst(exec_env);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
module_inst = wasm_program_get_root_module_from_inst(module_inst);
#endif
return module_inst;
}
void *
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
{
@ -1086,7 +1329,7 @@ wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
#endif
#if WASM_ENABLE_AOT != 0
if (module_type == Wasm_Module_AoT) {
AOTFunctionInstance *aot_func = (AOTFunctionInstance *)function;
AOTExportFunctionInstance *aot_func = (AOTExportFunctionInstance *)function;
type = aot_func->is_import_func ? aot_func->u.func_import->func_type
: aot_func->u.func.func_type;
}
@ -1179,7 +1422,7 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
#endif
#if WASM_ENABLE_AOT != 0
if (exec_env->module_inst->module_type == Wasm_Module_AoT)
ret = aot_call_function(exec_env, (AOTFunctionInstance *)function, argc,
ret = aot_call_function(exec_env, (AOTExportFunctionInstance *)function, argc,
argv);
#endif
@ -1436,7 +1679,7 @@ wasm_runtime_create_exec_env_and_call_wasm(
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT)
ret = aot_create_exec_env_and_call_function(
(AOTModuleInstance *)module_inst, (AOTFunctionInstance *)function,
(AOTModuleInstance *)module_inst, (AOTExportFunctionInstance *)function,
argc, argv);
#endif
return ret;
@ -1506,6 +1749,30 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst)
return NULL;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
const char*
wasm_runtime_get_program_exception(WASMProgramCommon *program_inst)
{
WASMProgramInstance * program = (WASMProgramInstance *)program_inst;
WASMModuleInstanceCommon * exception_inst = program->exception_inst;
if (!exception_inst)
return NULL;
#if WASM_ENABLE_INTERP != 0
if (exception_inst->module_type == Wasm_Module_Bytecode) {
return wasm_get_exception((WASMModuleInstance*)exception_inst);
}
#endif
#if WASM_ENABLE_AOT != 0
if (exception_inst->module_type == Wasm_Module_AoT) {
return aot_get_exception((AOTModuleInstance*)exception_inst);
}
#endif
return NULL;
}
#endif
void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst)
{
@ -2247,9 +2514,10 @@ wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
AOTFunctionInstance *export_funcs =
(AOTFunctionInstance *)aot_inst->export_funcs.ptr;
for (i = 0; i < aot_inst->export_func_count; i++) {
AOTModule * aot_module = (AOTModule *)aot_inst->aot_module.ptr;
AOTExportFunctionInstance *export_funcs = (AOTExportFunctionInstance *)
aot_inst->export_funcs.ptr;
for (i = 0; i < aot_module->export_func_count; i++) {
if (!strcmp(export_funcs[i].func_name, "_start")) {
AOTFuncType *func_type = export_funcs[i].u.func.func_type;
if (func_type->param_count != 0
@ -3186,7 +3454,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
uint64 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size, arg_i64;
uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
uint32 arg_i32, ptr_len;
uint32 arg_i32; //, ptr_len;
uint32 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
bool ret = false;
@ -3242,6 +3510,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
{
arg_i32 = *argv_src++;
arg_i64 = arg_i32;
#if 0
if (signature) {
if (signature[i + 1] == '*') {
/* param is a pointer */
@ -3269,6 +3538,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
module, arg_i32);
}
}
#endif
if (n_ints < MAX_REG_INTS)
ints[n_ints++] = arg_i64;
else
@ -3376,7 +3646,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false;
fail:
//fail:
if (argv1 != argv_buf)
wasm_runtime_free(argv1);
@ -3719,14 +3989,15 @@ static void
interp_mark_all_externrefs(WASMModuleInstance *module_inst)
{
uint32 i, j, externref_idx, *table_data;
uint8 *global_data = module_inst->global_data;
//uint8 *global_data = module_inst->global_data;
WASMGlobalInstance *global;
WASMTableInstance *table;
global = module_inst->globals;
for (i = 0; i < module_inst->global_count; i++, global++) {
if (global->type == VALUE_TYPE_EXTERNREF) {
externref_idx = *(uint32 *)(global_data + global->data_offset);
//externref_idx = *(uint32*)(global_data + global->data_offset);
externref_idx = *(uint32*)(global->data);
mark_externref(externref_idx);
}
}

View File

@ -12,6 +12,7 @@
#include "wasm_native.h"
#include "../include/wasm_export.h"
#include "../interpreter/wasm.h"
#include "wasm_multimodules_program.h"
#if WASM_ENABLE_LIBC_WASI != 0
#if WASM_ENABLE_UVWASI == 0
#include "wasmtime_ssp.h"
@ -25,6 +26,7 @@
extern "C" {
#endif
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
#define PUT_I64_TO_ADDR(addr, value) \
@ -295,6 +297,41 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
#if WASM_ENABLE_DYNAMIC_LINKING != 0
typedef struct DependencyModuleInitGlobals {
uint32 memory_base;
uint32 actual_memory_base;
uint32 table_base;
uint32 table_alignment;
uint32 table_size;
uint32 stack_pointer;
} DependencyModuleInitGlobals;
typedef struct WASMModuleInstanceHead {
uint32 module_type;
// unique instance id in program scope, used to alloc table space currently.
uint32 inst_id;
WASMRuntime * runtime;
WASMProgramInstance * program;
HashMap * local_implicit_dependency_modules_name_hmap;
DependencyModuleInitGlobals init_globals;
// explicit ref count, updated by dlopen/dlclose
uint32 exp_ref_cnt;
// implicit ref count, updated according to needed library entries
uint32 imp_ref_cnt;
#ifdef TARGET_32
uint32 padding_runtime;
uint32 padding_program;
uint32 padding_dep_hmap;
#endif
} WASMModuleInstanceHead;
#endif
typedef struct WASMProgramCommon {
uint8 module_data[1];
} WASMProgramCommon;
typedef struct WASMModuleCommon {
/* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode, and this structure should
@ -411,6 +448,11 @@ WASM_RUNTIME_API_EXTERN WASMModuleCommon *
wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleCommon *
wasm_runtime_load2(const char * name, const uint8 *buf, uint32 size,
char *error_buf, uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleCommon *
wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
@ -420,6 +462,27 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
WASM_RUNTIME_API_EXTERN void
wasm_runtime_unload(WASMModuleCommon *module);
WASM_RUNTIME_API_EXTERN WASMProgramCommon *
wasm_runtime_create_program(WASMModuleCommon * module, uint32 stack_size,
uint32 heap_size, uint32 dlopen_mode,
char * error_buf, uint32 error_buf_size);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_program(WASMProgramCommon* program);
/* Internal API */
/**
* load and instantiate a wasm module and its dependencies at runtime.
*
*/
//uint32
//wasm_runtime_open_dependencies(wasm_module_inst_t module_inst,
// const char * path, bool is_aot);
uint32
wasm_runtime_lookup_symbol_from_module(wasm_module_inst_t caller_module,
uint32 module_slot, const char * symbol);
/* Internal API */
WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
@ -431,6 +494,83 @@ void
wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst,
bool is_sub_inst);
WASMModuleCommon *
load_dependency_module_internal(module_reader reader, module_destroyer destroyer,
const char *sub_module_name, const uint32 name_len,
const package_type_t module_type, char *error_buf,
uint32 error_buf_size);
inline static uint32
const_str_hash(ConstStrDescription * key)
{
if (key->hash)
return key->hash;
/* take FNV-1a as hash function*/
uint32 hash = 2166136261u;
for (uint32 i = 0; i < key->len; i++) {
hash ^= (uint8)key->str[i];
hash *= 16777619;
}
key->hash = hash;
return hash;
}
inline static bool
const_str_equal(const ConstStrDescription * key1, const ConstStrDescription * key2)
{
if ((key1->hash != key2->hash) || (key1->len != key2->len))
return false;
return ((strncmp(key1->str, key2->str, key1->len) == 0) ? true : false);
}
inline static void
const_str_destroy_key(void *key)
{
if (!key)
return;
if (!((ConstStrDescription*)key)->is_sys_symbol)
wasm_runtime_free(key);
}
inline static void
const_str_destroy_value(void *value)
{
if (!value)
return;
wasm_runtime_free(value);
}
inline static void
const_str_destroy_module(void *module)
{
if (!module)
return;
wasm_runtime_unload((WASMModuleCommon*)module);
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
inline static void
const_str_destroy_module_inst(void *module_inst)
{
WASMModuleInstanceHead * inst_head = NULL;
bool is_sub_inst = true;
if (!module_inst)
return;
inst_head = (WASMModuleInstanceHead *)module_inst;
if (inst_head->program->root_module_inst == module_inst)
is_sub_inst = false;
wasm_runtime_deinstantiate_internal((WASMModuleInstanceCommon *)module_inst, is_sub_inst);
}
#endif
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
@ -464,6 +604,9 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env);
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_get_module_inst(WASMExecEnv *exec_env);
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_get_root_module_inst(WASMExecEnv *exec_env);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env);
@ -531,11 +674,19 @@ WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
char *argv[]);
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_program_main(WASMProgramCommon *program,
int32 argc, char *argv[]);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
const char *name, int32 argc, char *argv[]);
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_program_func(WASMProgramCommon *program,
const char *name, int32 argc, char *argv[]);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_exception(WASMModuleInstanceCommon *module,
@ -545,6 +696,10 @@ wasm_runtime_set_exception(WASMModuleInstanceCommon *module,
WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_exception(WASMModuleInstanceCommon *module);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_program_exception(WASMProgramCommon *progam);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
@ -629,7 +784,6 @@ void
wasm_runtime_set_llvm_stack(WASMModuleInstanceCommon *module_inst,
uint32 llvm_stack);
#if WASM_ENABLE_MULTI_MODULE != 0
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_module_reader(const module_reader reader,
const module_destroyer destroyer);
@ -640,6 +794,7 @@ wasm_runtime_get_module_reader();
module_destroyer
wasm_runtime_get_module_destroyer();
#if WASM_ENABLE_MULTI_MODULE != 0
bool
wasm_runtime_register_module_internal(const char *module_name,
WASMModuleCommon *module,
@ -670,6 +825,9 @@ wasm_runtime_destroy_loading_module_list();
bool
wasm_runtime_is_built_in_module(const char *module_name);
bool
wasm_runtime_is_built_in_module_new(WASMRuntime * runtime, const ConstStrDescription *module_name);
#if WASM_ENABLE_THREAD_MGR != 0
bool
wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset,

View File

@ -312,7 +312,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
if (module->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module;
AOTMemoryInstance *aot_memory =
((AOTMemoryInstance **)aot_inst->memories.ptr)[0];
(AOTMemoryInstance *)aot_inst->memories.ptr;
/* Currently we have only one memory instance */
if (!aot_memory->is_shared) {
wasm_runtime_set_exception(module, "wait on unshared memory");

View File

@ -0,0 +1,153 @@
#ifdef DEF_CONST_STRING
DEF_CONST_STRING(null, "")
DEF_CONST_STRING(env, "env")
DEF_CONST_STRING(GOT_func, "GOT.func")
DEF_CONST_STRING(wasi_unstable, "wasi_unstable")
DEF_CONST_STRING(wasi_snapshot_preview1, "wasi_snapshot_preview1")
DEF_CONST_STRING(spectest, "spectest")
DEF_CONST_STRING(memory, "memory")
DEF_CONST_STRING(var_stack_pointer, "__stack_pointer")
DEF_CONST_STRING(var_user_stack_pointer, "__user_stack_pointer")
DEF_CONST_STRING(var_memory_base, "__memory_base")
DEF_CONST_STRING(var_table_base, "__table_base")
DEF_CONST_STRING(var_data_end, "__data_end")
//AS
DEF_CONST_STRING(__alloc, "__alloc")
DEF_CONST_STRING(__free, "__free")
DEF_CONST_STRING(__realloc, "__realloc")
DEF_CONST_STRING(__new, "__new")
DEF_CONST_STRING(__pin, "__pin")
DEF_CONST_STRING(__unpin, "__unpin")
DEF_CONST_STRING(__collect, "__collect")
// libc
#if WASM_ENABLE_LIBC_BUILTIN != 0
DEF_CONST_STRING(iprintf, "iprintf")
DEF_CONST_STRING(printf, "printf")
DEF_CONST_STRING(sprintf, "sprintf")
DEF_CONST_STRING(snprintf, "snprintf")
DEF_CONST_STRING(puts, "puts")
DEF_CONST_STRING(putchar, "putchar")
DEF_CONST_STRING(memcmp, "memcmp")
DEF_CONST_STRING(memcpy, "memcpy")
DEF_CONST_STRING(memmove, "memmove")
DEF_CONST_STRING(memset, "memset")
DEF_CONST_STRING(strchr, "strchr")
DEF_CONST_STRING(strcmp, "strcmp")
DEF_CONST_STRING(strcpy, "strcpy")
DEF_CONST_STRING(strlen, "strlen")
DEF_CONST_STRING(strncmp, "strncmp")
DEF_CONST_STRING(strncpy, "strncpy")
DEF_CONST_STRING(malloc, "malloc")
DEF_CONST_STRING(realloc, "realloc")
DEF_CONST_STRING(calloc, "calloc")
DEF_CONST_STRING(strdup, "strdup")
DEF_CONST_STRING(_strdup, "_strdup")
DEF_CONST_STRING(free, "free")
DEF_CONST_STRING(atoi, "atoi")
DEF_CONST_STRING(exit, "exit")
DEF_CONST_STRING(strtol, "strtol")
DEF_CONST_STRING(strtoul, "strtoul")
DEF_CONST_STRING(strtod, "strtod")
DEF_CONST_STRING(memchr, "memchr")
DEF_CONST_STRING(strncasecmp, "strncasecmp")
DEF_CONST_STRING(strspn, "strspn")
DEF_CONST_STRING(strcspn, "strcspn")
DEF_CONST_STRING(strstr, "strstr")
DEF_CONST_STRING(isupper, "isupper")
DEF_CONST_STRING(isalpha, "isalpha")
DEF_CONST_STRING(isspace, "isspace")
DEF_CONST_STRING(isgraph, "isgraph")
DEF_CONST_STRING(isprint, "isprint")
DEF_CONST_STRING(isdigit, "isdigit")
DEF_CONST_STRING(isxdigit, "isxdigit")
DEF_CONST_STRING(tolower, "tolower")
DEF_CONST_STRING(toupper, "toupper")
DEF_CONST_STRING(__ctype_tolower_loc, "__ctype_tolower_loc")
DEF_CONST_STRING(isalnum, "isalnum")
DEF_CONST_STRING(setTempRet0, "setTempRet0")
DEF_CONST_STRING(getTempRet0, "getTempRet0")
DEF_CONST_STRING(llvm_bswap_i16, "llvm_bswap_i16")
DEF_CONST_STRING(llvm_bswap_i32, "llvm_bswap_i32")
DEF_CONST_STRING(bitshift64Lshr, "bitshift64Lshr")
DEF_CONST_STRING(bitshift64Shl, "bitshift64Shl")
DEF_CONST_STRING(llvm_stackrestore, "llvm_stackrestore")
DEF_CONST_STRING(llvm_stacksave, "llvm_stacksave")
DEF_CONST_STRING(emscripten_memcpy_big, "emscripten_memcpy_big")
DEF_CONST_STRING(abort, "abort")
DEF_CONST_STRING(AS_abort, "as_abort") // a placehold, won't be used in code.
DEF_CONST_STRING(abortStackOverflow, "abortStackOverflow")
DEF_CONST_STRING(nullFunc_X, "nullFunc_X")
DEF_CONST_STRING(__cxa_allocate_exception, "__cxa_allocate_exception")
DEF_CONST_STRING(__cxa_begin_catch, "__cxa_begin_catch")
DEF_CONST_STRING(__cxa_throw, "__cxa_throw")
DEF_CONST_STRING(clock_gettime, "clock_gettime")
DEF_CONST_STRING(clock, "clock")
DEF_CONST_STRING(dlopen, "dlopen")
DEF_CONST_STRING(dlsym, "dlsym")
//DEF_CONST_STRING(dltest, "dltest")
DEF_CONST_STRING(dlclose, "dlclose")
#endif
#if WASM_ENABLE_SPEC_TEST
//spec test
DEF_CONST_STRING(print, "print")
DEF_CONST_STRING(print_i32, "print_i32")
DEF_CONST_STRING(print_i32_f32, "print_i32_f32")
DEF_CONST_STRING(print_f64_f64, "print_f64_f64")
DEF_CONST_STRING(print_f32, "print_f32")
DEF_CONST_STRING(print_f64, "print_f64")
#endif
// libc wasi
#if WASM_ENABLE_LIBC_WASI != 0
DEF_CONST_STRING2(args_get)
DEF_CONST_STRING2(args_sizes_get)
DEF_CONST_STRING2(clock_res_get)
DEF_CONST_STRING2(clock_time_get)
DEF_CONST_STRING2(environ_get)
DEF_CONST_STRING2(environ_sizes_get)
DEF_CONST_STRING2(fd_prestat_get)
DEF_CONST_STRING2(fd_prestat_dir_name)
DEF_CONST_STRING2(fd_close)
DEF_CONST_STRING2(fd_datasync)
DEF_CONST_STRING2(fd_pread)
DEF_CONST_STRING2(fd_pwrite)
DEF_CONST_STRING2(fd_read)
DEF_CONST_STRING2(fd_renumber)
DEF_CONST_STRING2(fd_seek)
DEF_CONST_STRING2(fd_tell)
DEF_CONST_STRING2(fd_fdstat_get)
DEF_CONST_STRING2(fd_fdstat_set_flags)
DEF_CONST_STRING2(fd_fdstat_set_rights)
DEF_CONST_STRING2(fd_sync)
DEF_CONST_STRING2(fd_write)
DEF_CONST_STRING2(fd_advise)
DEF_CONST_STRING2(fd_allocate)
DEF_CONST_STRING2(path_create_directory)
DEF_CONST_STRING2(path_link)
DEF_CONST_STRING2(path_open)
DEF_CONST_STRING2(fd_readdir)
DEF_CONST_STRING2(path_readlink)
DEF_CONST_STRING2(path_rename)
DEF_CONST_STRING2(fd_filestat_get)
DEF_CONST_STRING2(fd_filestat_set_times)
DEF_CONST_STRING2(fd_filestat_set_size)
DEF_CONST_STRING2(path_filestat_get)
DEF_CONST_STRING2(path_filestat_set_times)
DEF_CONST_STRING2(path_symlink)
DEF_CONST_STRING2(path_unlink_file)
DEF_CONST_STRING2(path_remove_directory)
DEF_CONST_STRING2(poll_oneoff)
DEF_CONST_STRING2(proc_exit)
DEF_CONST_STRING2(proc_raise)
DEF_CONST_STRING2(random_get)
DEF_CONST_STRING2(sock_recv)
DEF_CONST_STRING2(sock_send)
DEF_CONST_STRING2(sock_shutdown)
DEF_CONST_STRING2(sched_yield)
#endif
#endif

View File

@ -61,7 +61,7 @@ aot_create_mem_init_data_list(const WASMModule *module)
/* Create each memory data segment */
for (i = 0; i < module->data_seg_count; i++) {
size = offsetof(AOTMemInitData, bytes)
+ (uint64)module->data_segments[i]->data_length;
+ (uint64)module->data_segments[i].data_length;
if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
@ -69,13 +69,13 @@ aot_create_mem_init_data_list(const WASMModule *module)
}
#if WASM_ENABLE_BULK_MEMORY != 0
data_list[i]->is_passive = module->data_segments[i]->is_passive;
data_list[i]->memory_index = module->data_segments[i]->memory_index;
data_list[i]->is_passive = module->data_segments[i].is_passive;
data_list[i]->memory_index = module->data_segments[i].memory_index;
#endif
data_list[i]->offset = module->data_segments[i]->base_offset;
data_list[i]->byte_count = module->data_segments[i]->data_length;
memcpy(data_list[i]->bytes, module->data_segments[i]->data,
module->data_segments[i]->data_length);
data_list[i]->offset = module->data_segments[i].base_offset;
data_list[i]->byte_count = module->data_segments[i].data_length;
memcpy(data_list[i]->bytes, module->data_segments[i].data,
module->data_segments[i].data_length);
}
return data_list;
@ -151,7 +151,8 @@ fail:
static AOTImportGlobal *
aot_create_import_globals(const WASMModule *module,
uint32 *p_import_global_data_size)
uint32 *p_import_global_data_size,
uint32 pointer_size)
{
AOTImportGlobal *import_globals;
uint64 size;
@ -174,12 +175,15 @@ aot_create_import_globals(const WASMModule *module,
import_globals[i].global_name = import_global->field_name;
import_globals[i].type = import_global->type;
import_globals[i].is_mutable = import_global->is_mutable;
import_globals[i].global_data_linked =
import_global->global_data_linked;
import_globals[i].global_data_linked = import_global->global_data_linked;
// patch for mutable global
if (!import_globals[i].is_mutable)
import_globals[i].size = wasm_value_type_size(import_global->type);
else
import_globals[i].size = pointer_size;
/* Calculate data offset */
import_globals[i].data_offset = data_offset;
data_offset += wasm_value_type_size(import_global->type);
data_offset += import_globals[i].size;
}
*p_import_global_data_size = data_offset;
@ -306,25 +310,20 @@ aot_create_import_funcs(const WASMModule *module)
}
static void
aot_destroy_funcs(AOTFunc **funcs, uint32 count)
aot_destroy_funcs(AOTFunc * funcs, uint32 count)
{
uint32 i;
for (i = 0; i < count; i++)
if (funcs[i])
wasm_runtime_free(funcs[i]);
wasm_runtime_free(funcs);
}
static AOTFunc **
static AOTFunc *
aot_create_funcs(const WASMModule *module)
{
AOTFunc **funcs;
AOTFunc *funcs = NULL;
uint64 size;
uint32 i, j;
/* Allocate memory */
size = sizeof(AOTFunc *) * (uint64)module->function_count;
size = sizeof(AOTFunc) * (uint64)module->function_count;
if (size >= UINT32_MAX || !(funcs = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
return NULL;
@ -335,39 +334,30 @@ aot_create_funcs(const WASMModule *module)
/* Create each function */
for (i = 0; i < module->function_count; i++) {
WASMFunction *func = module->functions[i];
size = sizeof(AOTFunc);
if (!(funcs[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed.");
goto fail;
}
funcs[i]->func_type = func->func_type;
funcs[i].func_type = func->func_type;
/* Resolve function type index */
for (j = 0; j < module->type_count; j++)
if (func->func_type == module->types[j]) {
funcs[i]->func_type_index = j;
funcs[i].func_type_index = j;
break;
}
/* Resolve local variable info and code info */
funcs[i]->local_count = func->local_count;
funcs[i]->local_types = func->local_types;
funcs[i]->param_cell_num = func->param_cell_num;
funcs[i]->local_cell_num = func->local_cell_num;
funcs[i]->code = func->code;
funcs[i]->code_size = func->code_size;
funcs[i].local_count = func->local_count;
funcs[i].local_types = func->local_types;
funcs[i].param_cell_num = func->func_type->param_cell_num;
funcs[i].local_cell_num = func->local_cell_num;
funcs[i].code = func->code;
funcs[i].code_size = func->code_size;
}
return funcs;
fail:
aot_destroy_funcs(funcs, module->function_count);
return NULL;
}
AOTCompData*
aot_create_comp_data(WASMModule *module)
aot_create_comp_data(WASMModule *module, uint32 pointer_size)
{
AOTCompData *comp_data;
uint32 import_global_data_size = 0, global_data_size = 0, i, j;
@ -486,17 +476,18 @@ aot_create_comp_data(WASMModule *module)
comp_data->import_global_count = module->import_global_count;
if (comp_data->import_global_count > 0
&& !(comp_data->import_globals =
aot_create_import_globals(module, &import_global_data_size)))
aot_create_import_globals(module, &import_global_data_size, pointer_size)))
goto fail;
/* Create globals */
comp_data->global_count = module->global_count;
if (comp_data->global_count
&& !(comp_data->globals = aot_create_globals(
module, import_global_data_size, &global_data_size)))
&& !(comp_data->globals = aot_create_globals
(module, import_global_data_size, &global_data_size)))
goto fail;
comp_data->global_data_size = import_global_data_size + global_data_size;
comp_data->global_data_size = import_global_data_size +
global_data_size;
/* Create function types */
comp_data->func_type_count = module->type_count;
@ -512,7 +503,8 @@ aot_create_comp_data(WASMModule *module)
/* Create functions */
comp_data->func_count = module->function_count;
if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
if (comp_data->func_count
&& !(comp_data->funcs = aot_create_funcs(module)))
goto fail;
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0

View File

@ -15,11 +15,15 @@
extern "C" {
#endif
#define AOT_FEATURE_ENABLE_DYNAMIC_LINKING 0x1
#define AOT_FEATURE_ENABLE_XIP_MODE (0x1 << 1)
#define AOT_FUNC_PREFIX "aot_func#"
typedef InitializerExpression AOTInitExpr;
typedef WASMType AOTFuncType;
typedef WASMExport AOTExport;
struct AOTCompContext;
#if WASM_ENABLE_DEBUG_AOT != 0
typedef void *dwar_extractor_handle_t;
@ -136,8 +140,8 @@ typedef struct AOTTableInitData {
* Import global variable
*/
typedef struct AOTImportGlobal {
char *module_name;
char *global_name;
const ConstStrDescription *module_name;
const ConstStrDescription *global_name;
/* VALUE_TYPE_I32/I64/F32/F64 */
uint8 type;
bool is_mutable;
@ -165,8 +169,8 @@ typedef struct AOTGlobal {
* Import function
*/
typedef struct AOTImportFunc {
char *module_name;
char *func_name;
const ConstStrDescription * module_name;
const ConstStrDescription *func_name;
AOTFuncType *func_type;
uint32 func_type_index;
/* function pointer after linked */
@ -237,7 +241,7 @@ typedef struct AOTCompData {
/* Functions */
uint32 func_count;
AOTFunc **funcs;
AOTFunc * funcs;
/* Custom name sections */
const uint8 *name_section_buf;
@ -273,7 +277,7 @@ typedef struct AOTNativeSymbol {
} AOTNativeSymbol;
AOTCompData*
aot_create_comp_data(WASMModule *module);
aot_create_comp_data(WASMModule *module, uint32 pointer_size);
void
aot_destroy_comp_data(AOTCompData *comp_data);

View File

@ -2822,16 +2822,21 @@ aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
goto fail1;
}
if (!(comp_data = aot_create_comp_data(wasm_module))) {
if (!(comp_ctx = aot_create_comp_context(&option))) {
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail2;
}
if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
if (!(comp_data = aot_create_comp_data(wasm_module, comp_ctx->pointer_size))) {
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail3;
}
if (!aot_bind_comp_context_data(comp_ctx, comp_data)) {
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail4;
}
if (!aot_compile_wasm(comp_ctx)) {
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail4;
@ -2855,12 +2860,15 @@ aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
*p_aot_file_size = aot_file_size;
fail4:
/* Destroy compiler context */
aot_destroy_comp_context(comp_ctx);
fail3:
/* Destroy compile data */
aot_destroy_comp_data(comp_data);
fail3:
/* Destroy compiler context */
aot_destroy_comp_context(comp_ctx);
fail2:
wasm_unload(wasm_module);
fail1:

View File

@ -173,7 +173,7 @@ static uint32
get_file_header_size()
{
/* magic number (4 bytes) + version (4 bytes) */
return sizeof(uint32) + sizeof(uint32);
return sizeof(uint32) + sizeof(uint32) + sizeof(uint64) + sizeof(uint32);
}
static uint32
@ -394,9 +394,10 @@ get_import_global_size(AOTCompContext *comp_ctx, AOTImportGlobal *import_global)
{
/* type (1 byte) + is_mutable (1 byte) + module_name + global_name */
uint32 size = (uint32)sizeof(uint8) * 2
+ get_string_size(comp_ctx, import_global->module_name);
+ get_string_size(comp_ctx, import_global->module_name->str);
size = align_uint(size, 2);
size += get_string_size(comp_ctx, import_global->global_name);
size += get_string_size(comp_ctx, import_global->global_name->str);
return size;
}
@ -463,9 +464,10 @@ get_import_func_size(AOTCompContext *comp_ctx, AOTImportFunc *import_func)
{
/* type index (2 bytes) + module_name + func_name */
uint32 size = (uint32)sizeof(uint16)
+ get_string_size(comp_ctx, import_func->module_name);
+ get_string_size(comp_ctx, import_func->module_name->str);
size = align_uint(size, 2);
size += get_string_size(comp_ctx, import_func->func_name);
size += get_string_size(comp_ctx, import_func->func_name->str);
return size;
}
@ -521,12 +523,38 @@ get_object_data_section_info_size(AOTCompContext *comp_ctx,
obj_data->data_sections_count);
}
static uint32
get_needed_lib_entries_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
{
uint32 size = (uint32)sizeof(uint32);
for (uint32 i = 0; i < comp_data->wasm_module->dylink_section->needed_dylib_count; i ++) {
bh_assert(comp_data->wasm_module->dylink_section->needed_dylib_entries[i]->len < (((uint32)0x1 << 16) - 1));
size = align_uint(size, 2);
size += get_string_size(comp_ctx, comp_data->wasm_module->dylink_section->needed_dylib_entries[i]->str);
//size += (uint32)sizeof(uint32) +
// comp_data->wasm_module->dylink_section->needed_dylib_entries[i].dylib_name_len;
}
return size;
}
static uint32
get_dylink_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
{
if (comp_data->wasm_module->dylink_section)
return (uint32)sizeof(uint32) * 4 +
get_needed_lib_entries_size(comp_ctx, comp_data);
else
return 0;
}
static uint32
get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTObjectData *obj_data)
{
uint32 size = 0;
size = align_uint(size, 4);
size += get_mem_info_size(comp_data);
size = align_uint(size, 4);
@ -890,6 +918,13 @@ get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
size += (uint32)sizeof(uint32) * 2;
size += get_target_info_section_size();
/* dylink section */
size = align_uint(size, 4);
/* section id + section size */
size += (uint32)sizeof(uint32) * 2;
size += get_dylink_section_size(comp_ctx, comp_data);
/* init data section */
size = align_uint(size, 4);
/* section id + section size */
@ -1278,6 +1313,11 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
{
uint32 offset = *p_offset;
uint32 aot_curr_version = AOT_CURRENT_VERSION;
uint64 features = 0;
/* currently, simply use the offset of field global_table_data in AOTModuleInstance as verifcation
TODO: take more field offsets and hash them as verification to monitor the changes to AOTModuleInstance.
*/
uint32 verification = offsetof(AOTModuleInstance, global_table_data.bytes);
EMIT_U8('\0');
EMIT_U8('a');
@ -1285,6 +1325,13 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U8('t');
EMIT_U32(aot_curr_version);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
features |= AOT_FEATURE_ENABLE_DYNAMIC_LINKING;
#endif
EMIT_U64(features);
EMIT_U32(verification);
bh_assert(offset == get_file_header_size());
*p_offset = offset;
return true;
@ -1484,9 +1531,9 @@ aot_emit_import_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
offset = align_uint(offset, 2);
EMIT_U8(import_global->type);
EMIT_U8(import_global->is_mutable);
EMIT_STR(import_global->module_name);
EMIT_STR(import_global->module_name->str);
offset = align_uint(offset, 2);
EMIT_STR(import_global->global_name);
EMIT_STR(import_global->global_name->str);
}
if (offset - *p_offset
@ -1547,9 +1594,9 @@ aot_emit_import_func_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
for (i = 0; i < comp_data->import_func_count; i++, import_func++) {
offset = align_uint(offset, 2);
EMIT_U16(import_func->func_type_index);
EMIT_STR(import_func->module_name);
EMIT_STR(import_func->module_name->str);
offset = align_uint(offset, 2);
EMIT_STR(import_func->func_name);
EMIT_STR(import_func->func_name->str);
}
if (offset - *p_offset != get_import_func_info_size(comp_ctx, comp_data)) {
@ -1593,6 +1640,38 @@ aot_emit_object_data_section_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
return true;
}
static bool
aot_emit_dylink_section(uint8 * buf, uint8 * buf_end, uint32 * p_offset,
AOTCompContext *comp_ctx, AOTCompData * comp_data)
{
uint32 section_size = get_dylink_section_size(comp_ctx, comp_data);
uint32 offset = *p_offset;
*p_offset = offset = align_uint(offset, 4);
EMIT_U32(AOT_SECTION_TYPE_DYLINK);
if (!comp_data->wasm_module->dylink_section)
EMIT_U32(0);
else {
EMIT_U32(section_size);
EMIT_U32(comp_data->wasm_module->dylink_section->memory_size);
EMIT_U32(comp_data->wasm_module->dylink_section->memory_alignment);
EMIT_U32(comp_data->wasm_module->dylink_section->table_size);
EMIT_U32(comp_data->wasm_module->dylink_section->table_alignment);
EMIT_U32(comp_data->wasm_module->dylink_section->needed_dylib_count);
for (uint32 i = 0; i < comp_data->wasm_module->dylink_section->needed_dylib_count; i ++) {
offset = align_uint(offset, 2);
EMIT_STR(comp_data->wasm_module->dylink_section->needed_dylib_entries[i]->str);
}
}
*p_offset = offset;
return true;
}
static bool
aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompContext *comp_ctx, AOTCompData *comp_data,
@ -1681,7 +1760,7 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
uint32 section_size = get_func_section_size(comp_data, obj_data);
uint32 i, offset = *p_offset;
AOTObjectFunc *func = obj_data->funcs;
AOTFunc **funcs = comp_data->funcs;
AOTFunc *funcs = comp_data->funcs;
*p_offset = offset = align_uint(offset, 4);
@ -1696,7 +1775,7 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
}
for (i = 0; i < comp_data->func_count; i++)
EMIT_U32(funcs[i]->func_type_index);
EMIT_U32(funcs[i].func_type_index);
if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
aot_set_last_error("emit function section failed.");
@ -2708,10 +2787,9 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
buf_end = buf + aot_file_size;
if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_target_info_section(buf, buf_end, &offset, comp_data,
obj_data)
|| !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx,
comp_data, obj_data)
|| !aot_emit_target_info_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_dylink_section(buf, buf_end, &offset, comp_ctx, comp_data)
|| !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx, comp_data, obj_data)
|| !aot_emit_text_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_func_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_export_section(buf, buf_end, &offset, comp_ctx, comp_data,

View File

@ -31,7 +31,7 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMPositionBuilderAtEnd(comp_ctx->builder,
func_ctx->got_exception_block);
/* Create exection id phi */
/* Create exception id phi */
if (!(func_ctx->exception_id_phi = LLVMBuildPhi(
comp_ctx->builder, I32_TYPE, "exception_id_phi"))) {
aot_set_last_error("llvm build phi failed.");

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,7 @@ static bool
compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 global_idx, bool is_set, bool is_aux_stack)
{
WASMRuntime * runtime = wasm_runtime_get_runtime();
AOTCompData *comp_data = comp_ctx->comp_data;
uint32 import_global_count = comp_data->import_global_count;
uint32 global_base_offset =
@ -116,8 +117,8 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ sizeof(AOTMemoryInstance) * comp_ctx->comp_data->memory_count;
uint32 global_offset;
uint8 global_type;
LLVMValueRef offset, global_ptr, global, res;
LLVMTypeRef ptr_type = NULL;
LLVMValueRef offset, global_ptr_ptr, global_ptr, global, res;
LLVMTypeRef ptr_type = NULL, mutable_ptr_type = NULL;
bh_assert(global_idx < import_global_count + comp_data->global_count);
@ -164,11 +165,47 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
break;
}
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr, ptr_type,
"global_ptr"))) {
// check if import mutable global
if (!(global_idx < import_global_count &&
comp_data->import_globals[global_idx].is_mutable &&
comp_data->import_globals[global_idx].module_name != CONST_STR_POOL_DESC(runtime, WAMR_CSP_GOT_func))) {
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr,
ptr_type, "global_ptr"))) {
aot_set_last_error("llvm build bit cast failed.");
return false;
}
} else {
// if yes, a pointer to origin value is saved in the global data
if (comp_ctx->pointer_size == sizeof(uint32))
mutable_ptr_type = comp_ctx->basic_types.int32_ptr_type;
else
mutable_ptr_type = comp_ctx->basic_types.int64_ptr_type;
if (!(global_ptr_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr,
mutable_ptr_type, "global_ptr_ptr"))) {
aot_set_last_error("llvm build bit cast failed.");
return false;
}
if (!(global_ptr = LLVMBuildLoad(comp_ctx->builder,
global_ptr_ptr, "global_ptr"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
if (!(global_ptr = LLVMBuildIntToPtr(comp_ctx->builder,
global_ptr,
ptr_type, "global_ptr"))) {
aot_set_last_error("llvm build bit cast failed.");
return false;
}
if (!(global = LLVMBuildLoad(comp_ctx->builder,
global_ptr, "global"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
}
if (!is_set) {
if (!(global =

View File

@ -902,7 +902,7 @@ aot_create_func_contexts(AOTCompData *comp_data, AOTCompContext *comp_ctx)
/* Create each function context */
for (i = 0; i < comp_data->func_count; i++) {
AOTFunc *func = comp_data->funcs[i];
AOTFunc *func = comp_data->funcs + i;
if (!(func_ctxes[i] =
aot_create_func_context(comp_data, comp_ctx, func, i))) {
aot_destroy_func_contexts(func_ctxes, comp_data->func_count);
@ -1363,8 +1363,28 @@ fail:
}
#endif /* WASM_ENABLE_LAZY_JIT != 0 */
bool
aot_bind_comp_context_data(AOTCompContext * comp_ctx, AOTCompData * comp_data)
{
comp_ctx->comp_data = comp_data;
/* Create function context for each function */
comp_ctx->func_ctx_count = comp_data->func_count;
if (comp_data->func_count > 0
&& !(comp_ctx->func_ctxes =
aot_create_func_contexts(comp_data, comp_ctx)))
return false;
return true;
}
uint32
aot_comp_ctx_get_pointer_size(AOTCompContext * comp_ctx)
{
return comp_ctx->pointer_size;
}
AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
aot_create_comp_context(aot_comp_option_t option)
{
AOTCompContext *comp_ctx, *ret = NULL;
#if WASM_ENABLE_LAZY_JIT == 0
@ -1403,7 +1423,6 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
}
memset(comp_ctx, 0, sizeof(AOTCompContext));
comp_ctx->comp_data = comp_data;
/* Create LLVM context, module and builder */
#if WASM_ENABLE_LAZY_JIT != 0
@ -1900,13 +1919,6 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
/* set aot_inst data type to int8* */
comp_ctx->aot_inst_type = INT8_PTR_TYPE;
/* Create function context for each function */
comp_ctx->func_ctx_count = comp_data->func_count;
if (comp_data->func_count > 0
&& !(comp_ctx->func_ctxes =
aot_create_func_contexts(comp_data, comp_ctx)))
goto fail;
if (cpu) {
uint32 len = (uint32)strlen(cpu) + 1;
if (!(comp_ctx->target_cpu = wasm_runtime_malloc(len))) {
@ -2337,7 +2349,7 @@ __call_llvm_intrinsic(const AOTCompContext *comp_ctx,
/* Call the LLVM intrinsic function */
if (!(ret = LLVMBuildCall(comp_ctx->builder, func, param_values,
(uint32)param_count, "call"))) {
(uint32)param_count, ""))) {
aot_set_last_error("llvm build intrinsic call failed.");
return NULL;
}
@ -2351,15 +2363,15 @@ aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
LLVMTypeRef ret_type, LLVMTypeRef *param_types,
int param_count, ...)
{
LLVMValueRef *param_values, ret;
LLVMValueRef *param_values = NULL, ret = NULL;
va_list argptr;
uint64 total_size;
int i = 0;
/* Create param values */
total_size = sizeof(LLVMValueRef) * (uint64)param_count;
if (total_size >= UINT32_MAX
|| !(param_values = wasm_runtime_malloc((uint32)total_size))) {
if (total_size > 0 && (total_size >= UINT32_MAX
|| !(param_values = wasm_runtime_malloc((uint32)total_size)))) {
aot_set_last_error("allocate memory for param values failed.");
return false;
}
@ -2373,11 +2385,18 @@ aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
ret = __call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, ret_type,
param_types, param_count, param_values);
if (param_values)
wasm_runtime_free(param_values);
return ret;
}
void
aot_call_debugtrap_intrinsic(const AOTCompContext *comp_ctx, const AOTFuncContext *func_ctx)
{
aot_call_llvm_intrinsic(comp_ctx, func_ctx, "llvm.debugtrap", VOID_TYPE, NULL, 0);
}
LLVMValueRef
aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const char *intrinsic,

View File

@ -366,8 +366,14 @@ typedef struct AOTCompOption {
uint32 bounds_checks;
} AOTCompOption, *aot_comp_option_t;
bool
aot_bind_comp_context_data(AOTCompContext * comp_ctx, AOTCompData * comp_data);
uint32
aot_comp_ctx_get_pointer_size(AOTCompContext * comp_ctx);
AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
aot_create_comp_context(aot_comp_option_t option);
void
aot_destroy_comp_context(AOTCompContext *comp_ctx);
@ -442,6 +448,9 @@ LLVMValueRef
aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
LLVMTypeRef func_type, int32 index);
void
aot_call_debugtrap_intrinsic(const AOTCompContext *comp_ctx, const AOTFuncContext *func_ctx);
bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);

View File

@ -20,7 +20,7 @@ struct AOTCompContext;
typedef struct AOTCompContext *aot_comp_context_t;
aot_comp_data_t
aot_create_comp_data(void *wasm_module);
aot_create_comp_data(void *wasm_module, uint32 pointer_size);
void
aot_destroy_comp_data(aot_comp_data_t comp_data);
@ -61,8 +61,14 @@ typedef struct AOTCompOption {
uint32_t bounds_checks;
} AOTCompOption, *aot_comp_option_t;
uint32_t
aot_comp_ctx_get_pointer_size(aot_comp_context_t comp_ctx);
bool
aot_bind_comp_context_data(aot_comp_context_t comp_ctx, aot_comp_data_t comp_data);
aot_comp_context_t
aot_create_comp_context(aot_comp_data_t comp_data, aot_comp_option_t option);
aot_create_comp_context(aot_comp_option_t option);
void
aot_destroy_comp_context(aot_comp_context_t comp_ctx);

View File

@ -7,13 +7,20 @@
#define _LIB_EXPORT_H_
#include <stdint.h>
#include "ConstStrDesc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
const char *symbol_str;
const ConstStrDescription * symbol;
uint32 symbol_key;
} NATIVE_SYMBOL_U;
typedef struct NativeSymbol {
const char *symbol;
NATIVE_SYMBOL_U u;
void *func_ptr;
const char *signature;
/* attachment which can be retrieved in native API by

View File

@ -63,6 +63,10 @@ struct WASMModuleCommon;
typedef struct WASMModuleCommon *wasm_module_t;
#endif
/* Instantiated multiple module program */
struct WASMProgramCommon;
typedef struct WASMProgramCommon *wasm_program_t;
/* Instantiated WASM module */
struct WASMModuleInstanceCommon;
typedef struct WASMModuleInstanceCommon *wasm_module_inst_t;
@ -138,6 +142,8 @@ typedef struct RuntimeInitArgs {
int platform_port;
int instance_port;
#endif
bool standalone;
bool auto_ext_name;
} RuntimeInitArgs;
#ifndef WASM_VALKIND_T_DEFINED
@ -299,6 +305,18 @@ WASM_RUNTIME_API_EXTERN wasm_module_t
wasm_runtime_load(const uint8_t *buf, uint32_t size,
char *error_buf, uint32_t error_buf_size);
WASM_RUNTIME_API_EXTERN wasm_module_t
wasm_runtime_load2(const char * name,
const uint8_t *buf, uint32_t size,
char *error_buf, uint32_t error_buf_size);
WASM_RUNTIME_API_EXTERN wasm_program_t
wasm_runtime_create_program(wasm_module_t module, uint32_t stack_size, uint32_t heap_size,
uint32 dlopen_mode, char * error_buf, uint32_t error_buf_size);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_program(wasm_program_t program);
/**
* Load a WASM module from a specified WASM or AOT section list.
*
@ -320,6 +338,8 @@ wasm_runtime_load_from_sections(wasm_section_list_t section_list, bool is_aot,
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_unload(wasm_module_t module);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_unload2(wasm_module_t module);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_wasi_args_ex(wasm_module_t module,
@ -439,6 +459,9 @@ wasm_runtime_destroy_thread_env(void);
WASM_RUNTIME_API_EXTERN wasm_module_inst_t
wasm_runtime_get_module_inst(wasm_exec_env_t exec_env);
WASM_RUNTIME_API_EXTERN wasm_module_inst_t
wasm_runtime_get_root_module_inst(wasm_exec_env_t exec_env);
/**
* Call the given WASM function of a WASM module instance with
* arguments (bytecode and AoT).
@ -523,6 +546,10 @@ WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_main(wasm_module_inst_t module_inst,
int32_t argc, char *argv[]);
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_program_main(wasm_program_t program_inst,
int32_t argc, char *argv[]);
/**
* Find the specified function in argv[0] from a WASM module instance
* and execute that function.
@ -541,6 +568,10 @@ wasm_application_execute_main(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_func(wasm_module_inst_t module_inst,
const char *name, int32_t argc, char *argv[]);
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_program_func(wasm_program_t program_inst,
const char *name, int32_t argc, char *argv[]);
/**
* Get exception info of the WASM module instance.
*
@ -551,6 +582,8 @@ wasm_application_execute_func(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_exception(wasm_module_inst_t module_inst);
WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_program_exception(wasm_program_t program_inst);
/**
* Set exception info of the WASM module instance.
*

View File

@ -9,6 +9,7 @@
#include "bh_platform.h"
#include "bh_hashmap.h"
#include "bh_assert.h"
#include "wasm_multimodules_program.h"
#ifdef __cplusplus
extern "C" {
@ -84,6 +85,7 @@ extern "C" {
#define LABEL_TYPE_IF 2
#define LABEL_TYPE_FUNCTION 3
typedef struct WASMModule WASMModule;
typedef struct WASMFunction WASMFunction;
typedef struct WASMGlobal WASMGlobal;
@ -143,7 +145,7 @@ typedef struct WASMMemory {
} WASMMemory;
typedef struct WASMTableImport {
char *module_name;
const char *module_name;
char *field_name;
uint8 elem_type;
uint32 flags;
@ -158,7 +160,7 @@ typedef struct WASMTableImport {
} WASMTableImport;
typedef struct WASMMemoryImport {
char *module_name;
const char *module_name;
char *field_name;
uint32 flags;
uint32 num_bytes_per_page;
@ -171,8 +173,8 @@ typedef struct WASMMemoryImport {
} WASMMemoryImport;
typedef struct WASMFunctionImport {
char *module_name;
char *field_name;
const ConstStrDescription *module_name;
const ConstStrDescription *field_name;
/* function type */
WASMType *func_type;
/* native function pointer after linked */
@ -191,8 +193,8 @@ typedef struct WASMFunctionImport {
} WASMFunctionImport;
typedef struct WASMGlobalImport {
char *module_name;
char *field_name;
const ConstStrDescription *module_name;
const ConstStrDescription *field_name;
uint8 type;
bool is_mutable;
/* global data after linked */
@ -214,25 +216,21 @@ typedef struct WASMImport {
WASMMemoryImport memory;
WASMGlobalImport global;
struct {
char *module_name;
char *field_name;
const ConstStrDescription *module_name;
const ConstStrDescription *field_name;
} names;
} u;
} WASMImport;
struct WASMFunction {
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
char *field_name;
const char *field_name;
#endif
/* the type of function */
WASMType *func_type;
uint32 local_count;
uint8 *local_types;
/* cell num of parameters */
uint16 param_cell_num;
/* cell num of return type */
uint16 ret_cell_num;
/* cell num of local variables */
uint16 local_cell_num;
/* offset of each local, including function parameters
@ -263,7 +261,7 @@ struct WASMGlobal {
};
typedef struct WASMExport {
char *name;
const char *name;
uint8 kind;
uint32 index;
} WASMExport;
@ -291,6 +289,20 @@ typedef struct WASMDataSeg {
uint8 *data;
} WASMDataSeg;
typedef struct WASMDylibEntry {
uint32 dylib_name_len;
const char * dylib_name_str;
} WASMDylibEntry;
typedef struct WASMDylinkSection {
uint32 memory_size;
uint32 memory_alignment;
uint32 table_size;
uint32 table_alignment;
uint32 needed_dylib_count;
const ConstStrDescription * needed_dylib_entries[0];
} WASMDylinkSection;
typedef struct BlockAddr {
const uint8 *start_addr;
uint8 *else_addr;
@ -356,6 +368,11 @@ struct WASMModule {
WASMImport *import_memories;
WASMImport *import_globals;
uint32 export_func_count;
uint32 export_global_count;
uint32 export_mem_count;
uint32 export_tab_count;
WASMType **types;
WASMImport *imports;
WASMFunction **functions;
@ -364,7 +381,8 @@ struct WASMModule {
WASMGlobal *globals;
WASMExport *exports;
WASMTableSeg *table_segments;
WASMDataSeg **data_segments;
WASMDataSeg *data_segments;
WASMDylinkSection *dylink_section;
uint32 start_function;
/* the index of auxiliary __data_end global,
@ -399,8 +417,14 @@ struct WASMModule {
/* Whether there is possible memory grow, e.g. memory.grow opcode */
bool possible_memory_grow;
StringList const_str_list;
WASMRuntime * runtime;
const uint8 * file_buf;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
/* directly implicit dependency modules of current module, e.g. dylink section */
HashMap *implicit_dependency_modules_hmap;
uint32 ref_cnt;
#endif
const ConstStrDescription * module_name;
#if WASM_ENABLE_LIBC_WASI != 0
WASIArguments wasi_args;
bool is_wasi_module;

View File

@ -22,7 +22,6 @@ typedef float32 CellType_F32;
typedef float64 CellType_F64;
#define BR_TABLE_TMP_BUF_LEN 32
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
@ -346,6 +345,7 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
do { \
frame = (new_frame); \
cur_func = frame->function; \
cur_func_type = cur_func->func_type; \
prev_frame = frame->prev_frame; \
frame_ip = frame->ip; \
RECOVER_FRAME_IP_END(); \
@ -571,12 +571,12 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
#define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
do { \
uint32 param_count = cur_func->param_count; \
uint32 param_count = cur_func_type->param_count; \
read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
bh_assert(local_idx < param_count + cur_func->local_count); \
local_offset = cur_func->local_offsets[local_idx]; \
if (local_idx < param_count) \
local_type = cur_func->param_types[local_idx]; \
local_type = cur_func_type->types[local_idx]; \
else \
local_type = cur_func->local_types[local_idx - param_count]; \
} while (0)
@ -759,6 +759,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMInterpFrame *prev_frame)
{
WASMFunctionImport *func_import = cur_func->u.func_import;
WASMType * func_type = func_import->func_type;
unsigned local_cell_num = 2;
WASMInterpFrame *frame;
uint32 argv_ret[2];
@ -779,7 +780,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (!func_import->func_ptr_linked) {
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
func_import->module_name, func_import->field_name);
(char*)func_import->module_name->str, (char*)func_import->field_name->str);
wasm_set_exception(module_inst, buf);
return;
}
@ -788,7 +789,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
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,
func_type->param_cell_num, frame->lp,
func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) {
argv_ret[0] = frame->lp[0];
@ -799,23 +800,23 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
ret = wasm_runtime_invoke_native(
exec_env, func_import->func_ptr_linked, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
func_type->param_cell_num, argv_ret);
}
else {
ret = wasm_runtime_invoke_native_raw(
exec_env, func_import->func_ptr_linked, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
func_type->param_cell_num, argv_ret);
}
if (!ret)
return;
if (cur_func->ret_cell_num == 1) {
if (func_type->ret_cell_num == 1) {
prev_frame->sp[0] = argv_ret[0];
prev_frame->sp++;
}
else if (cur_func->ret_cell_num == 2) {
else if (func_type->ret_cell_num == 2) {
prev_frame->sp[0] = argv_ret[0];
prev_frame->sp[1] = argv_ret[1];
prev_frame->sp += 2;
@ -825,13 +826,48 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
}
#if WASM_ENABLE_MULTI_MODULE != 0
static void
wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static void
wasm_interp_call_inter_module_func(WASMModuleInstance *module_inst,
WASMModuleInstance *callee_module_inst,
WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame)
{
uint8 *ip = prev_frame->ip;
/* set ip NULL to make call_func_bytecode return after executing
this function */
prev_frame->ip = NULL;
/* replace exec_env's module_inst with sub_module_inst so we can
call it */
exec_env->module_inst = (WASMModuleInstanceCommon *)callee_module_inst;
/* call function of sub-module*/
wasm_interp_call_func_bytecode(callee_module_inst, exec_env,
cur_func, prev_frame);
/* restore ip and module_inst */
prev_frame->ip = ip;
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
/* transfer exception if it is thrown */
if (wasm_get_exception(callee_module_inst)) {
bh_memcpy_s(module_inst->cur_exception,
sizeof(module_inst->cur_exception),
callee_module_inst->cur_exception,
sizeof(callee_module_inst->cur_exception));
}
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
static void
wasm_interp_call_func_import(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env,
@ -847,7 +883,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
if (!sub_func_inst) {
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
func_import->module_name, func_import->field_name);
func_import->module_name->str, func_import->field_name->str);
wasm_set_exception(module_inst, buf);
return;
}
@ -948,15 +984,19 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
static inline uint8 *
get_global_addr(uint8 *global_data, WASMGlobalInstance *global)
get_global_addr(WASMGlobalInstance *global)
{
#if WASM_ENABLE_MULTI_MODULE == 0
return global_data + global->data_offset;
//return global_data + global->data_offset;
return global->data;
#else
//return global->import_global_inst
// ? global->import_module_inst->global_data
// + global->import_global_inst->data_offset
// : global_data + global->data_offset;
return global->import_global_inst
? global->import_module_inst->global_data
+ global->import_global_inst->data_offset
: global_data + global->data_offset;
? global->import_global_inst->data
: global->data;
#endif
}
@ -968,15 +1008,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
WASMMemoryInstance *memory = module->default_memory;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data;
uint32 linear_mem_size =
memory ? num_bytes_per_page * memory->cur_page_count : 0;
//#if WASM_ENABLE_MULTI_MODULE == 1
//uint8 *global_data = module->global_data;
//#endif
uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->globals, *global;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
WASMInterpFrame *frame = NULL;
/* Points to this special opcode so as to jump to the
* call_method_from_entry. */
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMProgramInstance * program = module->program;
#endif
WASMModuleInstance * callee_module_inst = NULL;
WASMType * cur_func_type = cur_func->func_type;
/* Points to this special opcode so as to jump to the call_method_from_entry. */
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
register uint32 *frame_lp = NULL; /* cache of frame->lp */
register uint32 *frame_sp = NULL; /* cache of frame->sp */
@ -1131,8 +1176,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
POP_CSP();
}
else { /* end of function, treat as WASM_OP_RETURN */
frame_sp -= cur_func->ret_cell_num;
for (i = 0; i < cur_func->ret_cell_num; i++) {
frame_sp -= cur_func_type->ret_cell_num;
for (i = 0; i < cur_func_type->ret_cell_num; i++) {
*prev_frame->sp++ = frame_sp[i];
}
goto return_func;
@ -1190,8 +1235,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_RETURN)
{
frame_sp -= cur_func->ret_cell_num;
for (i = 0; i < cur_func->ret_cell_num; i++) {
frame_sp -= cur_func_type->ret_cell_num;
for (i = 0; i < cur_func_type->ret_cell_num; i++) {
*prev_frame->sp++ = frame_sp[i];
}
goto return_func;
@ -1211,6 +1256,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#endif
cur_func = module->functions + fidx;
callee_module_inst = module;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (!wasm_program_resolve_op_call(program, module, &callee_module_inst, &cur_func)) {
goto got_exception;
}
#endif
cur_func_type = cur_func->func_type;
goto call_func_from_interp;
}
@ -1228,7 +1280,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
#endif
cur_func = module->functions + fidx;
cur_func_type = cur_func->func_type;
goto call_func_from_return_call;
}
#endif /* WASM_ENABLE_TAIL_CALL */
@ -1238,9 +1290,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
#endif
{
WASMType *cur_type, *cur_func_type;
WASMTableInstance *tbl_inst;
WASMType *cur_type;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0
opcode = *(frame_ip - 1);
#endif
@ -1261,9 +1313,28 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
val = POP_I32();
#if WASM_ENABLE_DYNAMIC_LINKING != 0
cur_func = wasm_program_lookup_cached_resolving_func(program, val);
if (!cur_func) {
if (!wasm_program_resolve_op_call_indirect(program, module,
tbl_idx, val,
cur_type,
&callee_module_inst,
&cur_func)) {
goto got_exception;
}
bh_assert(callee_module_inst == cur_func->module_inst);
} else {
callee_module_inst = cur_func->module_inst;
}
cur_func_type = cur_func->func_type;
#else
WASMTableInstance *tbl_inst;
callee_module_inst = module;
tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
wasm_set_exception(module, "undefined element");
goto got_exception;
@ -1280,22 +1351,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
* another module. In that case, we don't validate
* the elem value while loading
*/
if (fidx >= module->function_count) {
if (fidx >= callee_module_inst->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
/* always call module own functions */
cur_func = module->functions + fidx;
cur_func = callee_module_inst->functions + fidx;
cur_func_type = cur_func->func_type;
if (cur_func->is_import_func)
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
wasm_set_exception(module, "indirect call type mismatch");
goto got_exception;
}
#endif
#if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;
@ -1549,7 +1619,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
PUSH_I32(*(uint32 *)global_addr);
HANDLE_OP_END();
}
@ -1559,7 +1629,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
PUSH_I64(GET_I64_FROM_ADDR((uint32 *)global_addr));
HANDLE_OP_END();
}
@ -1569,7 +1639,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
*(int32 *)global_addr = POP_I32();
HANDLE_OP_END();
}
@ -1581,7 +1651,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
aux_stack_top = *(uint32 *)(frame_sp - 1);
if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
wasm_set_exception(module, "wasm auxiliary stack overflow");
@ -1610,7 +1680,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
PUT_I64_TO_ADDR((uint32 *)global_addr, POP_I64());
HANDLE_OP_END();
}
@ -2914,9 +2984,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
seg_len = (uint64)module->module->data_segments[segment]
->data_length;
data = module->module->data_segments[segment]->data;
seg_len = (uint64)module->module->data_segments[segment].data_length;
data = module->module->data_segments[segment].data;
if (offset + bytes > seg_len)
goto out_of_bounds;
@ -2929,7 +2998,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 segment;
read_leb_uint32(frame_ip, frame_ip_end, segment);
module->module->data_segments[segment]->data_length = 0;
module->module->data_segments[segment].data_length = 0;
break;
}
@ -3079,6 +3148,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
+ offsetof(WASMTableInstance, base_addr)
+ s * sizeof(uint32),
(uint32)(n * sizeof(uint32)));
#if WASM_ENABLE_DYNAMIC_LINKING != 0
/* invalidate all entries related to current instance, an opt could be applied which only invalidate impacted table elem id.*/
wasm_program_invalidate_cached_wasm_func(program, (WASMModuleInstanceCommon*)module);
#endif
break;
}
case WASM_OP_TABLE_GROW:
@ -3562,8 +3635,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_TAIL_CALL != 0
call_func_from_return_call:
{
POP(cur_func->param_cell_num);
word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
POP(cur_func_type->param_cell_num);
word_copy(frame->lp, frame_sp, cur_func_type->param_cell_num);
FREE_FRAME(exec_env, frame);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
goto call_func_from_entry;
@ -3573,14 +3646,40 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
/* Only do the copy when it's called from interpreter. */
WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env);
POP(cur_func->param_cell_num);
POP(cur_func_type->param_cell_num);
SYNC_ALL_TO_FRAME();
word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
word_copy(outs_area->lp, frame_sp, cur_func_type->param_cell_num);
prev_frame = frame;
}
call_func_from_entry:
{
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (callee_module_inst && module != callee_module_inst) {
bh_assert(!cur_func->is_import_func);
wasm_interp_call_inter_module_func(module,
callee_module_inst,
exec_env,
cur_func,
prev_frame);
prev_frame = frame->prev_frame;
cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */
memory = module->default_memory;
if (memory)
linear_mem_size = num_bytes_per_page * memory->cur_page_count;
if (wasm_get_exception(callee_module_inst))
goto got_exception;
callee_module_inst = NULL;
} else
#endif
{
if (cur_func->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0
if (cur_func->import_func_inst) {
@ -3596,6 +3695,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
prev_frame = frame->prev_frame;
cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */
@ -3607,11 +3707,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
else {
WASMFunction *cur_wasm_func = cur_func->u.func;
WASMType *func_type;
func_type = cur_wasm_func->func_type;
all_cell_num = (uint64)cur_func->param_cell_num
all_cell_num = (uint64)cur_func_type->param_cell_num
+ (uint64)cur_func->local_cell_num
+ (uint64)cur_wasm_func->max_stack_cell_num
+ ((uint64)cur_wasm_func->max_block_num)
@ -3634,7 +3731,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_lp = frame->lp;
frame_sp = frame->sp_bottom =
frame_lp + cur_func->param_cell_num + cur_func->local_cell_num;
frame_lp + cur_func_type->param_cell_num + cur_func->local_cell_num;
frame->sp_boundary =
frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
@ -3644,11 +3741,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame->csp_bottom + cur_wasm_func->max_block_num;
/* Initialize the local variables */
memset(frame_lp + cur_func->param_cell_num, 0,
memset(frame_lp + cur_func_type->param_cell_num, 0,
(uint32)(cur_func->local_cell_num * 4));
/* Push function block as first block */
cell_num = func_type->ret_cell_num;
cell_num = cur_func_type->ret_cell_num;
PUSH_CSP(LABEL_TYPE_FUNCTION, cell_num, frame_ip_end - 1);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame);
@ -3656,6 +3753,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_SUSPEND_FLAGS();
#endif
}
}
HANDLE_OP_END();
}
@ -3699,19 +3797,20 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
{
WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
WASMInterpFrame *frame, *outs_area;
WASMType * func_type = function->func_type;
/* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num =
function->ret_cell_num > 2 ? function->ret_cell_num : 2,
func_type->ret_cell_num > 2 ? func_type->ret_cell_num : 2,
i;
/* This frame won't be used by JITed code, so only allocate interp
frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
if (argc != function->param_cell_num) {
if (argc != func_type->param_cell_num) {
char buf[128];
snprintf(buf, sizeof(buf), "invalid argument count %d, expected %d",
argc, function->param_cell_num);
argc, func_type->param_cell_num);
wasm_set_exception(module_inst, buf);
return;
}
@ -3757,8 +3856,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) {
for (i = 0; i < function->ret_cell_num; i++) {
argv[i] = *(frame->sp + i - function->ret_cell_num);
for (i = 0; i < func_type->ret_cell_num; i++) {
argv[i] = *(frame->sp + i - func_type->ret_cell_num);
}
}
else {

View File

@ -228,12 +228,12 @@ LOAD_PTR(void *addr)
#define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
do { \
uint32 param_count = cur_func->param_count; \
uint32 param_count = cur_func_type->param_count; \
local_idx = read_uint32(frame_ip); \
bh_assert(local_idx < param_count + cur_func->local_count); \
local_offset = cur_func->local_offsets[local_idx]; \
if (local_idx < param_count) \
local_type = cur_func->param_types[local_idx]; \
local_type = cur_func_type->types[local_idx]; \
else \
local_type = cur_func->local_types[local_idx - param_count]; \
} while (0)
@ -322,6 +322,7 @@ LOAD_PTR(void *addr)
do { \
frame = (new_frame); \
cur_func = frame->function; \
cur_func_type = cur_func->func_type;\
prev_frame = frame->prev_frame; \
frame_ip = frame->ip; \
UPDATE_FRAME_IP_END(); \
@ -830,6 +831,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMInterpFrame *prev_frame)
{
WASMFunctionImport *func_import = cur_func->u.func_import;
WASMType * func_type = cur_func->func_type;
unsigned local_cell_num = 2;
WASMInterpFrame *frame;
uint32 argv_ret[2];
@ -850,7 +852,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
char buf[128];
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
func_import->module_name, func_import->field_name);
func_import->module_name->str, func_import->field_name->str);
wasm_set_exception((WASMModuleInstance*)module_inst, buf);
return;
}
@ -858,8 +860,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,
func_import->func_ptr_linked, func_type,
func_type->param_cell_num, frame->lp,
func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) {
argv_ret[0] = frame->lp[0];
@ -868,24 +870,24 @@ 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, func_import->func_ptr_linked, func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
func_type->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, func_import->func_ptr_linked, func_type,
func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret);
func_type->param_cell_num, argv_ret);
}
if (!ret)
return;
if (cur_func->ret_cell_num == 1) {
if (func_type->ret_cell_num == 1) {
prev_frame->lp[prev_frame->ret_offset] = argv_ret[0];
}
else if (cur_func->ret_cell_num == 2) {
else if (func_type->ret_cell_num == 2) {
prev_frame->lp[prev_frame->ret_offset] = argv_ret[0];
prev_frame->lp[prev_frame->ret_offset + 1] = argv_ret[1];
}
@ -894,13 +896,48 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
}
#if WASM_ENABLE_MULTI_MODULE != 0
static void
wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static void
wasm_interp_call_inter_module_func(WASMModuleInstance *module_inst,
WASMModuleInstance *callee_module_inst,
WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame)
{
uint8 *ip = prev_frame->ip;
/* set ip NULL to make call_func_bytecode return after executing
this function */
prev_frame->ip = NULL;
/* replace exec_env's module_inst with sub_module_inst so we can
call it */
exec_env->module_inst = (WASMModuleInstanceCommon *)callee_module_inst;
/* call function of sub-module*/
wasm_interp_call_func_bytecode(callee_module_inst, exec_env,
cur_func, prev_frame);
/* restore ip and module_inst */
prev_frame->ip = ip;
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
/* transfer exception if it is thrown */
if (wasm_get_exception(callee_module_inst)) {
bh_memcpy_s(module_inst->cur_exception,
sizeof(module_inst->cur_exception),
callee_module_inst->cur_exception,
sizeof(callee_module_inst->cur_exception));
}
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
static void
wasm_interp_call_func_import(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env,
@ -916,7 +953,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
if (!sub_func_inst) {
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
func_import->module_name, func_import->field_name);
func_import->module_name->str, func_import->field_name->str);
wasm_set_exception(module_inst, buf);
return;
}
@ -1029,15 +1066,19 @@ static void **global_handle_table;
#endif
static inline uint8 *
get_global_addr(uint8 *global_data, WASMGlobalInstance *global)
get_global_addr(WASMGlobalInstance *global)
{
#if WASM_ENABLE_MULTI_MODULE == 0
return global_data + global->data_offset;
//return global_data + global->data_offset;
return global->data;
#else
//return global->import_global_inst
// ? global->import_module_inst->global_data
// + global->import_global_inst->data_offset
// : global_data + global->data_offset;
return global->import_global_inst
? global->import_module_inst->global_data
+ global->import_global_inst->data_offset
: global_data + global->data_offset;
? global->import_global_inst->data
: global->data;
#endif
}
@ -1049,14 +1090,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
WASMMemoryInstance *memory = module->default_memory;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data;
uint32 linear_mem_size =
memory ? num_bytes_per_page * memory->cur_page_count : 0;
//#if WASM_ENABLE_MULTI_MODULE == 1
// uint8 *global_data = module->global_data;
//#endif
uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMGlobalInstance *globals = module->globals, *global;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
WASMInterpFrame *frame = NULL;
/* Points to this special opcode so as to jump to the
* call_method_from_entry. */
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMProgramInstance * program = module->program;
#endif
WASMModuleInstance * callee_module_inst = NULL;
WASMType * cur_func_type = NULL;
/* Points to this special opcode so as to jump to the call_method_from_entry. */
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
register uint32 *frame_lp = NULL; /* cache of frame->lp */
#if WASM_ENABLE_LABELS_AS_VALUES != 0
@ -1084,6 +1130,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
#endif
cur_func_type = cur_func->func_type;
#if WASM_ENABLE_LABELS_AS_VALUES == 0
while (frame_ip < frame_ip_end) {
opcode = *frame_ip++;
@ -1223,8 +1271,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
#endif
{
WASMType *cur_type, *cur_func_type;
WASMTableInstance *tbl_inst;
WASMType *cur_type;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0
@ -1240,12 +1287,33 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
val = GET_OPERAND(uint32, I32, 0);
frame_ip += 2;
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
#if WASM_ENABLE_DYNAMIC_LINKING != 0
cur_func = wasm_program_lookup_cached_resolving_func(program, val);
if (!cur_func) {
if (!wasm_program_resolve_op_call_indirect(program, module,
tbl_idx, val,
cur_type,
&callee_module_inst,
&cur_func)) {
goto got_exception;
}
bh_assert(callee_module_inst == cur_func->module_inst);
} else {
callee_module_inst = cur_func->module_inst;
}
cur_func_type = cur_func->func_type;
#else
WASMTableInstance *tbl_inst;
callee_module_inst = module;
tbl_inst = wasm_get_table_inst(module, tbl_idx);
if (val < 0 ||
(val >= (int32)tbl_inst->cur_size
)) {
wasm_set_exception(module, "undefined element");
goto got_exception;
}
@ -1261,22 +1329,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
* another module. in that case, we don't validate
* the elem value while loading
*/
if (fidx >= module->function_count) {
if (fidx >= callee_module_inst->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
/* always call module own functions */
cur_func = module->functions + fidx;
cur_func = callee_module_inst->functions + fidx;
cur_func_type = cur_func->func_type;
if (cur_func->is_import_func)
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
wasm_set_exception(module, "indirect call type mismatch");
goto got_exception;
}
#endif
#if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;
@ -1427,7 +1494,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
addr_ret = GET_OFFSET();
frame_lp[addr_ret] = *(uint32 *)global_addr;
HANDLE_OP_END();
@ -1438,7 +1505,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
addr_ret = GET_OFFSET();
PUT_I64_TO_ADDR(frame_lp + addr_ret,
GET_I64_FROM_ADDR((uint32 *)global_addr));
@ -1450,7 +1517,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
addr1 = GET_OFFSET();
*(int32 *)global_addr = frame_lp[addr1];
HANDLE_OP_END();
@ -1463,7 +1530,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
aux_stack_top = frame_lp[GET_OFFSET()];
if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
wasm_set_exception(module, "wasm auxiliary stack overflow");
@ -1491,7 +1558,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
global_addr = get_global_addr(global);
addr1 = GET_OFFSET();
PUT_I64_TO_ADDR((uint32 *)global_addr,
GET_I64_FROM_ADDR(frame_lp + addr1));
@ -2845,9 +2912,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
seg_len = (uint64)module->module->data_segments[segment]
->data_length;
data = module->module->data_segments[segment]->data;
seg_len = (uint64)module->module->data_segments[segment].data_length;
data = module->module->data_segments[segment].data;
if (offset + bytes > seg_len)
goto out_of_bounds;
@ -2861,7 +2927,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
segment = read_uint32(frame_ip);
module->module->data_segments[segment]->data_length = 0;
module->module->data_segments[segment].data_length = 0;
break;
}
@ -3004,6 +3070,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
+ offsetof(WASMTableInstance, base_addr)
+ s * sizeof(uint32),
(uint32)(n * sizeof(uint32)));
#if WASM_ENABLE_DYNAMIC_LINKING != 0
/* invalidate all entries related to current instance, an opt could be applied which only invalidate impacted table elem id.*/
wasm_program_invalidate_cached_wasm_func(program, (WASMModuleInstanceCommon*)module);
#endif
break;
}
case WASM_OP_TABLE_GROW:
@ -3426,6 +3496,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
#endif
cur_func = module->functions + fidx;
callee_module_inst = module;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (!wasm_program_resolve_op_call(program, module, &callee_module_inst, &cur_func)) {
goto got_exception;
}
#if 0
// lazy link, resolve the import function.
if (program && module->inst_id && cur_func->is_import_func &&
!cur_func->u.func_import->func_ptr_linked) {
if (!cur_func->import_module_inst &&
!cur_func->import_func_inst) {
if (program->config.binding_mode != LAZY_BINDING) {
wasm_set_exception(module, "uninitialized import function.");
goto got_exception;
}
if (!wasm_program_resolve_wasm_function(program, module, cur_func)) {
char buf[128];
snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)",
(char*)cur_func->u.func_import->module_name->str,
(char*)cur_func->u.func_import->field_name->str);
wasm_set_exception(module, buf);
goto got_exception;
}
callee_module_inst = cur_func->import_module_inst;
cur_func = cur_func->import_func_inst;
} else {
callee_module_inst = cur_func->import_module_inst;
cur_func = cur_func->import_func_inst;
}
}
#endif
#endif
cur_func_type = cur_func->func_type;
goto call_func_from_interp;
}
@ -3443,6 +3550,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
#endif
cur_func = module->functions + fidx;
cur_func_type = cur_func->func_type;
goto call_func_from_return_call;
}
#endif /* WASM_ENABLE_TAIL_CALL */
@ -3522,22 +3630,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 *lp;
int i;
if (!(lp_base = lp = wasm_runtime_malloc(cur_func->param_cell_num
if (!(lp_base = lp = wasm_runtime_malloc(cur_func_type->param_cell_num
* sizeof(uint32)))) {
wasm_set_exception(module, "allocate memory failed");
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) {
for (i = 0; i < cur_func_type->param_count; i++) {
if (cur_func_type->types[i] == VALUE_TYPE_I64
|| cur_func->types[i] == VALUE_TYPE_F64) {
PUT_I64_TO_ADDR(
lp, GET_OPERAND(uint64, I64,
2 * (cur_func->param_count - i - 1)));
2 * (cur_func_type->param_count - i - 1)));
lp += 2;
}
else {
*lp = GET_OPERAND(uint32, I32,
(2 * (cur_func->param_count - i - 1)));
(2 * (cur_func_type->param_count - i - 1)));
lp++;
}
}
@ -3545,7 +3653,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
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);
frame_ip += cur_func_type->param_count * sizeof(int16);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
goto call_func_from_entry;
}
@ -3569,23 +3677,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
outs_area->lp = outs_area->operand + cur_func->const_cell_num;
}
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) {
for (i = 0; i < cur_func_type->param_count; i++) {
if (cur_func_type->types[i] == VALUE_TYPE_I64
|| cur_func_type->types[i] == VALUE_TYPE_F64) {
PUT_I64_TO_ADDR(
outs_area->lp,
GET_OPERAND(uint64, I64,
2 * (cur_func->param_count - i - 1)));
2 * (cur_func_type->param_count - i - 1)));
outs_area->lp += 2;
}
else {
*outs_area->lp = GET_OPERAND(
uint32, I32, (2 * (cur_func->param_count - i - 1)));
uint32, I32, (2 * (cur_func_type->param_count - i - 1)));
outs_area->lp++;
}
}
frame_ip += cur_func->param_count * sizeof(int16);
if (cur_func->ret_cell_num != 0) {
frame_ip += cur_func_type->param_count * sizeof(int16);
if (cur_func_type->ret_cell_num != 0) {
/* Get the first return value's offset. Since loader emit
* all return values' offset so we must skip remain return
* values' offsets.
@ -3604,6 +3712,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
call_func_from_entry:
{
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (callee_module_inst && module != callee_module_inst) {
wasm_interp_call_inter_module_func(module,
callee_module_inst,
exec_env,
cur_func,
prev_frame);
prev_frame = frame->prev_frame;
cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */
memory = module->default_memory;
if (memory)
linear_mem_size = num_bytes_per_page * memory->cur_page_count;
if (wasm_get_exception(callee_module_inst))
goto got_exception;
callee_module_inst = NULL;
} else
#endif
{
if (cur_func->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0
if (cur_func->import_func_inst) {
@ -3619,6 +3751,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
prev_frame = frame->prev_frame;
cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */
@ -3631,7 +3764,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
else {
WASMFunction *cur_wasm_func = cur_func->u.func;
all_cell_num = (uint64)cur_func->param_cell_num
all_cell_num = (uint64)cur_func_type->param_cell_num
+ (uint64)cur_func->local_cell_num
+ (uint64)cur_func->const_cell_num
+ (uint64)cur_wasm_func->max_stack_cell_num;
@ -3651,19 +3784,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_ip = wasm_get_func_code(cur_func);
frame_ip_end = wasm_get_func_code_end(cur_func);
frame_lp = frame->lp =
frame->operand + cur_wasm_func->const_cell_num;
frame_lp = frame->lp = 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);
/* Initialize the local variables */
memset(frame_lp + cur_func->param_cell_num, 0,
memset(frame_lp + cur_func_type->param_cell_num, 0,
(uint32)(cur_func->local_cell_num * 4));
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame);
}
}
HANDLE_OP_END ();
}
@ -3720,19 +3853,20 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
{
WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
WASMInterpFrame *frame, *outs_area;
WASMType * func_type = function->func_type;
/* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num =
function->ret_cell_num > 2 ? function->ret_cell_num : 2,
func_type->ret_cell_num > 2 ? func_type->ret_cell_num : 2,
i;
/* This frame won't be used by JITed code, so only allocate interp
frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
if (argc != function->param_cell_num) {
if (argc != func_type->param_cell_num) {
char buf[128];
snprintf(buf, sizeof(buf), "invalid argument count %d, expected %d",
argc, function->param_cell_num);
argc, func_type->param_cell_num);
wasm_set_exception(module_inst, buf);
return;
}
@ -3780,7 +3914,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) {
for (i = 0; i < function->ret_cell_num; i++)
for (i = 0; i < func_type->ret_cell_num; i++)
argv[i] = *(frame->lp + i);
}
else {

View File

@ -20,6 +20,9 @@
#define TEMPLATE_READ_VALUE(Type, p) \
(p += sizeof(Type), *(Type *)(p - sizeof(Type)))
#define CUSTOM_SECTION_DYNAMIC_LINK_SECTION_NAME ("dylink")
#define CUSTOM_SECTION_DYNAMIC_LINK_NAME_LEN (sizeof("dylink") - 1)
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
@ -347,67 +350,6 @@ check_utf8_str(const uint8 *str, uint32 len)
return (p == p_end);
}
static char *
const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
StringNode *node, *node_next;
if (!check_utf8_str(str, len)) {
set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
return NULL;
}
if (len == 0) {
return "";
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading, we use
the previous byte of leb encoded size to adjust the string:
move string 1 byte backward and then append '\0' */
char *c_str = (char *)str - 1;
bh_memmove_s(c_str, len + 1, c_str + 1, len);
c_str[len] = '\0';
return c_str;
}
/* Search const str list */
node = module->const_str_list;
while (node) {
node_next = node->next;
if (strlen(node->str) == len && !memcmp(node->str, str, len))
break;
node = node_next;
}
if (node) {
return node->str;
}
if (!(node = loader_malloc(sizeof(StringNode) + len + 1, error_buf,
error_buf_size))) {
return NULL;
}
node->str = ((char *)node) + sizeof(StringNode);
bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if (!module->const_str_list) {
/* set as head */
module->const_str_list = node;
node->next = NULL;
}
else {
/* insert it */
node->next = module->const_str_list;
module->const_str_list = node;
}
return node->str;
}
static bool
load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, char *error_buf,
@ -1018,15 +960,17 @@ delete_loading_module:
static bool
load_function_import(const uint8 **p_buf, const uint8 *buf_end,
const WASMModule *parent_module,
const char *sub_module_name, const char *function_name,
WASMFunctionImport *function, char *error_buf,
uint32 error_buf_size)
const ConstStrDescription *sub_module_name,
const ConstStrDescription *function_name,
WASMFunctionImport *function,
char *error_buf, uint32 error_buf_size)
{
const uint8 *p = *p_buf, *p_end = buf_end;
uint32 declare_type_index = 0;
WASMType *declare_func_type = NULL;
WASMFunction *linked_func = NULL;
#if WASM_ENABLE_MULTI_MODULE != 0
WASMRuntime * runtime = parent_module->runtime;
WASMModule *sub_module = NULL;
#endif
const char *linked_signature = NULL;
@ -1051,29 +995,34 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end,
declare_func_type = parent_module->types[declare_type_index];
/* lookup registered native symbols first */
linked_func = wasm_native_resolve_symbol(
sub_module_name, function_name, declare_func_type, &linked_signature,
&linked_attachment, &linked_call_conv_raw);
linked_func = wasm_native_resolve_symbol(sub_module_name,
&function_name,
declare_func_type,
&linked_signature,
&linked_attachment,
&linked_call_conv_raw);
if (linked_func) {
is_native_symbol = true;
}
#if WASM_ENABLE_MULTI_MODULE != 0
else {
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
if (!wasm_runtime_is_built_in_module_new(runtime, sub_module_name)) {
sub_module = load_depended_module(parent_module, (char*)sub_module_name->str,
error_buf, error_buf_size);
if (!sub_module) {
return false;
}
}
linked_func = wasm_loader_resolve_function(
sub_module_name, function_name, declare_func_type, error_buf,
linked_func = wasm_loader_resolve_function((char*)sub_module_name->str,
(char*)function_name->str,
declare_func_type,
error_buf,
error_buf_size);
}
#endif
function->module_name = (char *)sub_module_name;
function->field_name = (char *)function_name;
function->module_name = sub_module_name;
function->field_name = function_name;
function->func_type = declare_func_type;
/* func_ptr_linked is for native registered symbol */
function->func_ptr_linked = is_native_symbol ? linked_func : NULL;
@ -1343,9 +1292,11 @@ fail:
static bool
load_global_import(const uint8 **p_buf, const uint8 *buf_end,
const WASMModule *parent_module, char *sub_module_name,
char *global_name, WASMGlobalImport *global, char *error_buf,
uint32 error_buf_size)
const WASMModule *parent_module,
const ConstStrDescription *sub_module_name,
const ConstStrDescription *global_name,
WASMGlobalImport *global,
char *error_buf, uint32 error_buf_size)
{
const uint8 *p = *p_buf, *p_end = buf_end;
uint8 declare_type = 0;
@ -1367,7 +1318,8 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_LIBC_BUILTIN != 0
global->is_linked = wasm_native_lookup_libc_builtin_global(
sub_module_name, global_name, global);
(char*)sub_module_name->str,
(char*)global_name->str, global);
if (global->is_linked) {
if (global->type != declare_type
|| global->is_mutable != declare_mutable) {
@ -1379,16 +1331,17 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
if (!global->is_linked
&& !wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
&& !wasm_runtime_is_built_in_module((char*)sub_module_name->str)) {
sub_module = load_depended_module(parent_module, (char*)sub_module_name->str,
error_buf, error_buf_size);
if (!sub_module) {
return false;
}
/* check sub modules */
linked_global = wasm_loader_resolve_global(
sub_module_name, global_name, declare_type, declare_mutable,
linked_global =
wasm_loader_resolve_global((char*)sub_module_name->str, (char*)global_name->str,
declare_type, declare_mutable,
error_buf, error_buf_size);
if (linked_global) {
global->import_module = sub_module;
@ -1548,7 +1501,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
WASMImport *import;
WASMImport *import_functions = NULL, *import_tables = NULL;
WASMImport *import_memories = NULL, *import_globals = NULL;
char *sub_module_name, *field_name;
const ConstStrDescription *sub_module_name = NULL;
const ConstStrDescription * field_name = NULL;
uint8 u8, kind;
read_leb_uint32(p, p_end, import_count);
@ -1651,21 +1605,23 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load module name */
read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len);
if (!(sub_module_name = const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) {
if (!(sub_module_name = wasm_runtime_records_const_string(module->runtime,
(const char*)p, name_len, error_buf, error_buf_size))) {
return false;
}
p += name_len;
/* load field name */
read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len);
if (!(field_name = const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) {
if (!(field_name = wasm_runtime_records_const_string(module->runtime,
(const char*)p, name_len, error_buf, error_buf_size))) {
return false;
}
p += name_len;
CHECK_BUF(p, p_end, 1);
@ -1686,11 +1642,12 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
case IMPORT_KIND_TABLE: /* import table */
bh_assert(import_tables);
import = import_tables++;
if (!load_table_import(&p, p_end, module, sub_module_name,
field_name, &import->u.table,
if (!load_table_import(&p, p_end, module,
(char*)sub_module_name->str, (char*)field_name->str,
&import->u.table,
error_buf, error_buf_size)) {
LOG_DEBUG("can not import such a table (%s,%s)",
sub_module_name, field_name);
(char*)sub_module_name->str, field_name);
return false;
}
break;
@ -1698,8 +1655,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
case IMPORT_KIND_MEMORY: /* import memory */
bh_assert(import_memories);
import = import_memories++;
if (!load_memory_import(&p, p_end, module, sub_module_name,
field_name, &import->u.memory,
if (!load_memory_import(&p, p_end, module,
(char*)sub_module_name->str, (char*)field_name->str,
&import->u.memory,
error_buf, error_buf_size)) {
return false;
}
@ -1728,9 +1686,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
#if WASM_ENABLE_LIBC_WASI != 0
import = module->import_functions;
for (i = 0; i < module->import_function_count; i++, import++) {
if (!strcmp(import->u.names.module_name, "wasi_unstable")
|| !strcmp(import->u.names.module_name,
"wasi_snapshot_preview1")) {
if (!strcmp((char*)import->u.names.module_name->str, "wasi_unstable")
|| !strcmp((char*)import->u.names.module_name->str, "wasi_snapshot_preview1")) {
module->is_wasi_module = true;
break;
}
@ -1785,7 +1742,7 @@ init_function_local_offsets(WASMFunction *func, char *error_buf,
local_offset += wasm_value_type_cell_num(local_types[i]);
}
bh_assert(local_offset == func->param_cell_num + func->local_cell_num);
bh_assert(local_offset == func->func_type->param_cell_num + func->local_cell_num);
return true;
}
@ -1934,8 +1891,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
}
}
func->param_cell_num = func->func_type->param_cell_num;
func->ret_cell_num = func->func_type->ret_cell_num;
func->local_cell_num =
wasm_get_cell_num(func->local_types, func->local_count);
@ -2138,6 +2094,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
uint32 str_len;
WASMExport *export;
const char *name;
const ConstStrDescription * key_export_name = NULL;
read_leb_uint32(p, p_end, export_count);
@ -2163,11 +2120,12 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
}
}
if (!(export->name = const_str_list_insert(
p, str_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) {
key_export_name = wasm_runtime_records_const_string(module->runtime,
(const char*)p, str_len, error_buf, error_buf_size);
if (!key_export_name) {
return false;
}
export->name = key_export_name->str;
p += str_len;
CHECK_BUF(p, p_end, 1);
@ -2190,6 +2148,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
report error */
#endif
#endif
module->export_func_count ++;
break;
/* table index */
case EXPORT_KIND_TABLE:
@ -2199,6 +2158,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown table");
return false;
}
module->export_tab_count++;
break;
/* memory index */
case EXPORT_KIND_MEMORY:
@ -2208,6 +2168,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown memory");
return false;
}
module->export_mem_count++;
break;
/* global index */
case EXPORT_KIND_GLOBAL:
@ -2217,6 +2178,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown global");
return false;
}
module->export_global_count++;
break;
default:
set_error_buf(error_buf, error_buf_size,
@ -2510,9 +2472,9 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
if (data_seg_count) {
module->data_seg_count = data_seg_count;
total_size = sizeof(WASMDataSeg *) * (uint64)data_seg_count;
if (!(module->data_segments =
loader_malloc(total_size, error_buf, error_buf_size))) {
total_size = sizeof(WASMDataSeg) * (uint64)data_seg_count;
if (!(module->data_segments = loader_malloc
(total_size, error_buf, error_buf_size))) {
return false;
}
@ -2564,10 +2526,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
read_leb_uint32(p, p_end, data_seg_len);
if (!(dataseg = module->data_segments[i] = loader_malloc(
sizeof(WASMDataSeg), error_buf, error_buf_size))) {
return false;
}
dataseg = &module->data_segments[i];
#if WASM_ENABLE_BULK_MEMORY != 0
dataseg->is_passive = is_passive;
@ -2704,6 +2663,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
uint32 previous_func_index = ~0U;
uint32 func_name_len;
uint32 name_index;
const ConstStrDescription * key_func_name = NULL;
int i = 0;
if (p >= p_end) {
@ -2750,20 +2710,19 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
read_leb_uint32(p, p_end, func_name_len);
CHECK_BUF(p, p_end, func_name_len);
/* Skip the import functions */
if (func_index >= module->import_count) {
func_index -= module->import_count;
if (func_index >= module->import_function_count) {
func_index -= module->import_function_count;
if (func_index >= module->function_count) {
set_error_buf(error_buf, error_buf_size,
"out-of-range function index");
return false;
}
if (!(module->functions[func_index]->field_name =
const_str_list_insert(
p, func_name_len, module,
is_load_from_file_buf, error_buf,
error_buf_size))) {
key_func_name = wasm_runtime_records_const_string(module->runtime,
(const char*)p, func_name_len, error_buf, error_buf_size);
if (!key_func_name) {
return false;
}
module->functions[func_index]->field_name = key_func_name->str;
}
p += func_name_len;
}
@ -2785,6 +2744,184 @@ fail:
}
#endif
inline static WASMModule *
dylib_entries_map_find(ConstStrDescription * key, HashMap *map)
{
return bh_hash_map_find(map, (void*)key);
}
inline static bool
dylib_entries_map_insert(const ConstStrDescription * key, const WASMModule * module, HashMap *map)
{
//ConstStrDescription * key = NULL;
//if (bh_hash_map_find(map, (void*)key)) {
// return true;
//}
//if (!(key = loader_malloc(sizeof(ConstStrDescription),
// NULL, 0))) {
// return false;
//}
//bh_memcpy_s(key, sizeof(ConstStrDescription), tmp_key, sizeof(ConstStrDescription));
if (!bh_hash_map_insert_with_dup(map, (void*)key, (void*)module)) {
// wasm_runtime_free(key);
return false;
}
return true;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static bool
handle_dylink_section(const uint8 *buf, const uint8 *buf_end,
WASMModule *module,
char *error_buf, uint32 error_buf_size)
{
const uint8 *p = buf, *p_end = buf_end;
WASMDylinkSection tmp_dylink_section;
int32 step = 0;
uint32 total_size = 0;
uint32 name_len = 0;
const ConstStrDescription * key = NULL;
WASMRuntime * runtime = module->runtime;
WASMModule * dependency_module;
#define DYLINK_SECTION_MIN_SIZE (5)
if ((p + DYLINK_SECTION_MIN_SIZE) > p_end) {
set_error_buf(error_buf, error_buf_size, "unexpected end");
return false;
}
// read dylink section body
//
// Field Type Description
// memorysize varuint32 Size of the memory area the loader
// should reserve for the module, which will begin at env.__memory_base
// memoryalignment varuint32 The required alignment of the memory area, in bytes, encoded as a power of 2.
// tablesize varuint32 Size of the table area the loader should
// reserve for the module, which will begin at env.__table_base
// tablealignment varuint32 The required alignment of the table area, in elements, encoded as a power of 2.
// needed_dynlibs_count varuint32 Number of needed shared libraries
// needed_dynlibs_entries dynlib_entry* Repeated dynamic library entries as described below
// read dylink section base info.
while (p < p_end) {
switch (step) {
case 0:
read_leb_uint32(p, p_end, tmp_dylink_section.memory_size);
break;
case 1:
read_leb_uint32(p, p_end, tmp_dylink_section.memory_alignment);
break;
case 2:
read_leb_uint32(p, p_end, tmp_dylink_section.table_size);
break;
case 3:
read_leb_uint32(p, p_end, tmp_dylink_section.table_alignment);
break;
case 4:
read_leb_uint32(p, p_end, tmp_dylink_section.needed_dylib_count);
break;
default:
break;
}
step ++;
if (step >= 5)
break;
}
if (p > p_end) {
set_error_buf(error_buf, error_buf_size, "unexpected end");
return false;
}
// unsupport to load dependency recursively now
// bh_assert(tmp_dylink_section.needed_dylib_count == 0);
// create current module's dependencies map.
/*
if (tmp_dylink_section.needed_dylib_count > 0) {
if (!module->implicit_dependency_modules_hmap) {
module->implicit_dependency_modules_hmap = bh_hash_map_create(8, false,
(HashFunc)const_str_hash,
(KeyEqualFunc)const_str_equal,
NULL,
NULL);
if (!module->implicit_dependency_modules_hmap) {
set_error_buf(error_buf, error_buf_size,
"create local dependencies map failed");
return false;
}
}
}
*/
// calculate the total size which all entries will take.
total_size = tmp_dylink_section.needed_dylib_count * sizeof(ConstStrDescription*);
total_size += sizeof(WASMDylinkSection);
// alloc the entire memory to contain all data in dylink section,
// including base info and name string etc.
if (!(module->dylink_section = loader_malloc
(total_size, error_buf, error_buf_size))) {
return false;
}
bh_memcpy_s(module->dylink_section, sizeof(WASMDylinkSection),
&tmp_dylink_section, sizeof(WASMDylinkSection));
// read entries data
// records dylib entries in the module. not be sure if it is necessary
// after all we have dependencies map in module already.
for (uint32 i = 0; i < tmp_dylink_section.needed_dylib_count; i ++) {
read_leb_uint32(p, p_end, name_len);
// records string into const string pool
key = wasm_runtime_records_const_string(module->runtime, (const char*)p, name_len, error_buf, error_buf_size);
if (!key) {
wasm_runtime_free(module->dylink_section);
return false;
}
p += name_len;
module->dylink_section->needed_dylib_entries[i] = key;
//if (dylib_entries_map_find((ConstStrDescription *)key, module->implicit_dependency_modules_hmap))
// continue;
if (!runtime->config.need_load_dependencies)
continue;
dependency_module = (WASMModule*)load_implicit_dependency_module((const WASMModuleCommon *)module,
(ConstStrDescription *)key,
error_buf, error_buf_size);
if (!dependency_module) {
set_error_buf_v(error_buf, error_buf_size, "unknown import %s",
key->str);
return false;
}
// record the dependencies of current module.
// if (!dylib_entries_map_insert(key, dependency_module,
// module->implicit_dependency_modules_hmap)) {
// wasm_runtime_free(module->dylink_section);
// return false;
//}
}
return true;
fail:
if (module->dylink_section) {
wasm_runtime_free(module->dylink_section);
}
return false;
}
#endif
static bool
load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
@ -2818,6 +2955,14 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
error_buf_size);
}
#endif
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (name_len == CUSTOM_SECTION_DYNAMIC_LINK_NAME_LEN &&
memcmp(p, CUSTOM_SECTION_DYNAMIC_LINK_SECTION_NAME, CUSTOM_SECTION_DYNAMIC_LINK_NAME_LEN) == 0) {
p += name_len;
if (!handle_dylink_section(p, p_end, module, error_buf, error_buf_size))
return false;
}
#endif
LOG_VERBOSE("Load custom section success.\n");
return true;
@ -3226,6 +3371,14 @@ create_module(char *error_buf, uint32 error_buf_size)
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
bh_list_init(&module->fast_opcode_list);
#endif
module->runtime = wasm_runtime_get_runtime();
module->file_buf = NULL;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
// initial dependency related attributes.
module->implicit_dependency_modules_hmap = NULL;
module->module_name = NULL;
module->ref_cnt = 0;
#endif
return module;
}
@ -3512,21 +3665,18 @@ wasm_loader_unload(WASMModule *module)
}
if (module->data_segments) {
for (i = 0; i < module->data_seg_count; i++) {
if (module->data_segments[i])
wasm_runtime_free(module->data_segments[i]);
}
wasm_runtime_free(module->data_segments);
}
if (module->const_str_list) {
StringNode *node = module->const_str_list, *node_next;
while (node) {
node_next = node->next;
wasm_runtime_free(node);
node = node_next;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (module->dylink_section) {
wasm_runtime_free(module->dylink_section);
}
if (module->implicit_dependency_modules_hmap) {
bh_hash_map_destroy(module->implicit_dependency_modules_hmap);
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
/* just release the sub module list */
@ -3559,6 +3709,10 @@ wasm_loader_unload(WASMModule *module)
fast_opcode = next;
}
#endif
if (module->file_buf)
wasm_runtime_free((void*)module->file_buf);
wasm_runtime_free(module);
}
@ -4470,8 +4624,8 @@ wasm_loader_ctx_init(WASMFunction *func)
memset(loader_ctx->const_buf, 0, loader_ctx->const_buf_size);
loader_ctx->start_dynamic_offset = loader_ctx->dynamic_offset =
loader_ctx->max_dynamic_offset =
func->param_cell_num + func->local_cell_num;
loader_ctx->max_dynamic_offset = func->func_type->param_cell_num +
func->local_cell_num;
#endif
return loader_ctx;

View File

@ -874,7 +874,7 @@ init_function_local_offsets(WASMFunction *func, char *error_buf,
local_offset += wasm_value_type_cell_num(local_types[i]);
}
bh_assert(local_offset == func->param_cell_num + func->local_cell_num);
bh_assert(local_offset == func->func_type->param_cell_num + func->local_cell_num);
return true;
}
@ -983,8 +983,6 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
}
}
func->param_cell_num = func->func_type->param_cell_num;
func->ret_cell_num = func->func_type->ret_cell_num;
func->local_cell_num =
wasm_get_cell_num(func->local_types, func->local_count);

File diff suppressed because it is too large Load Diff

View File

@ -80,7 +80,8 @@ struct WASMGlobalInstance {
/* mutable or constant */
bool is_mutable;
/* data offset to base_addr of WASMMemoryInstance */
uint32 data_offset;
uint8 * data;
// uint32 data_offset;
/* initial value */
WASMValue initial_value;
#if WASM_ENABLE_MULTI_MODULE != 0
@ -91,16 +92,17 @@ struct WASMGlobalInstance {
};
struct WASMFunctionInstance {
/* the owner module instance */
WASMModuleInstance * module_inst;
/* whether it is import function or WASM function */
bool is_import_func;
/* parameter count */
uint16 param_count;
/* function signature*/
WASMType * func_type;
/* local variable count, 0 for import function */
uint16 local_count;
/* cell num of parameters */
uint16 param_cell_num;
/* cell num of return type */
uint16 ret_cell_num;
/* cell num of local variables, 0 for import function */
uint16 local_cell_num;
#if WASM_ENABLE_FAST_INTERP != 0
@ -108,15 +110,14 @@ struct WASMFunctionInstance {
uint16 const_cell_num;
#endif
uint16 *local_offsets;
/* parameter types */
uint8 *param_types;
/* local types, NULL for import function */
uint8 *local_types;
union {
WASMFunctionImport *func_import;
WASMFunction *func;
} u;
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
WASMModuleInstance *import_module_inst;
WASMFunctionInstance *import_func_inst;
#endif
@ -129,13 +130,13 @@ struct WASMFunctionInstance {
};
typedef struct WASMExportFuncInstance {
char *name;
const char * name;
WASMFunctionInstance *function;
} WASMExportFuncInstance;
#if WASM_ENABLE_MULTI_MODULE != 0
//#if WASM_ENABLE_MULTI_MODULE != 0
typedef struct WASMExportGlobInstance {
char *name;
const char *name;
WASMGlobalInstance *global;
} WASMExportGlobInstance;
@ -148,7 +149,7 @@ typedef struct WASMExportMemInstance {
char *name;
WASMMemoryInstance *memory;
} WASMExportMemInstance;
#endif
//#endif
struct WASMModuleInstance {
/* Module instance type, for module instance loaded from
@ -157,14 +158,26 @@ struct WASMModuleInstance {
Wasm_Module_AoT, and this structure should be treated as
AOTModuleInstance structure. */
uint32 module_type;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
//WASMModuleInstanceHead head;
// unique instance id in program scope, used to alloc table space currently.
uint32 inst_id;
WASMRuntime * runtime;
WASMProgramInstance * program;
HashMap * local_implicit_dependency_modules_name_hmap;
DependencyModuleInitGlobals init_globals;
// explicit ref count, updated by dlopen/dlclose
uint32 exp_ref_cnt;
// implicit ref count, updated according to needed library entries
uint32 imp_ref_cnt;
#endif
uint32 memory_count;
uint32 table_count;
uint32 global_count;
uint32 function_count;
uint32 export_func_count;
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
uint32 export_glob_count;
uint32 export_mem_count;
uint32 export_tab_count;
@ -176,7 +189,7 @@ struct WASMModuleInstance {
WASMFunctionInstance *functions;
WASMExportFuncInstance *export_functions;
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
WASMExportGlobInstance *export_globals;
WASMExportMemInstance *export_memories;
WASMExportTabInstance *export_tables;
@ -289,8 +302,16 @@ void
wasm_unload(WASMModule *module);
WASMModuleInstance *
wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
uint32 heap_size, char *error_buf, uint32 error_buf_size);
wasm_instantiate(WASMProgramInstance * program,
WASMModule *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMModuleInstance*
wasm_instantiate_dependency(WASMModule *module, WASMProgramInstance * program,
uint32 stack_size, DependencyModuleInitGlobals * init_globals);
#endif
void
wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
@ -413,11 +434,11 @@ wasm_elem_is_declarative(uint32 mode)
{
return (mode & 0x3) == 0x3;
}
#endif /* WASM_ENABLE_REF_TYPES != 0 */
bool
wasm_enlarge_table(WASMModuleInstance *module_inst, uint32 table_idx,
uint32 inc_entries, uint32 init_val);
#endif /* WASM_ENABLE_REF_TYPES != 0 */
static inline WASMTableInstance *
wasm_get_table_inst(const WASMModuleInstance *module_inst, const uint32 tbl_idx)

View File

@ -16,6 +16,9 @@
#define get_module(exec_env) \
wasm_exec_env_get_module(exec_env)
#define get_root_module_inst(exec_env) \
wasm_runtime_get_root_module_inst(exec_env)
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
@ -1035,7 +1038,7 @@ static int32
posix_memalign_wrapper(wasm_exec_env_t exec_env, void **memptr, int32 align,
int32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
void *p = NULL;
*((int32 *)memptr) = module_malloc(size, (void **)&p);

View File

@ -5,6 +5,7 @@
#include "bh_common.h"
#include "bh_log.h"
#include "ConstStrDesc.h"
#include "wasm_export.h"
#include "../interpreter/wasm.h"
@ -36,6 +37,9 @@ wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, uint32 size,
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
#define get_root_module_inst(exec_env) \
wasm_runtime_get_root_module_inst(exec_env)
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
@ -467,11 +471,17 @@ printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
wasm_module_inst_t module_inst = get_module_inst(exec_env);
struct str_context ctx = { NULL, 0, 0 };
/* format has been checked by runtime */
if (!validate_native_addr(va_args, sizeof(int32)))
if (!validate_app_str_addr((uint32)(uintptr_t)format))
return 0;
if (!_vprintf_wa((out_func_t)printf_out, &ctx, format, va_args,
/* format has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)va_args, sizeof(int32)))
return 0;
char * native_fmt = addr_app_to_native((uint32)(uintptr_t)format);
_va_list native_va_args = addr_app_to_native((uint32)(uintptr_t)va_args);
if (!_vprintf_wa((out_func_t)printf_out, &ctx, native_fmt, native_va_args,
module_inst))
return 0;
@ -479,33 +489,50 @@ printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
}
static int
sprintf_wrapper(wasm_exec_env_t exec_env, char *str, const char *format,
_va_list va_args)
iprintf_wrapper(wasm_exec_env_t exec_env,
const char * format, _va_list va_args)
{
return printf_wrapper(exec_env, format, va_args);
}
static int
sprintf_wrapper(wasm_exec_env_t exec_env,
char *str, const char *format, _va_list va_args)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint8 *native_end_offset;
struct str_context ctx;
/* str and format have been checked by runtime */
if (!validate_native_addr(va_args, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)str, 1))
return 0;
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)str, NULL,
if (!validate_app_str_addr((uint32)(uintptr_t)format))
return 0;
/* str and format have been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)va_args, sizeof(int32)))
return 0;
char * native_str = addr_app_to_native((uint32)(uintptr_t)str);
char * native_fmt = addr_app_to_native((uint32)(uintptr_t)format);
_va_list native_va_args = addr_app_to_native((uint32)(uintptr_t)va_args);
if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)native_str, NULL,
&native_end_offset)) {
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
return false;
}
ctx.str = str;
ctx.max = (uint32)(native_end_offset - (uint8 *)str);
ctx.str = native_str;
ctx.max = (uint32)(native_end_offset - (uint8 *)native_str);
ctx.count = 0;
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args,
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, native_fmt, native_va_args,
module_inst))
return 0;
if (ctx.count < ctx.max) {
str[ctx.count] = '\0';
native_str[ctx.count] = '\0';
}
return (int)ctx.count;
@ -518,20 +545,29 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
wasm_module_inst_t module_inst = get_module_inst(exec_env);
struct str_context ctx;
/* str and format have been checked by runtime */
if (!validate_native_addr(va_args, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)str, size))
return 0;
ctx.str = str;
if (!validate_app_str_addr((uint32)(uintptr_t)format))
return 0;
if (!validate_app_addr((uint32)(uintptr_t)va_args, sizeof(int32)))
return 0;
char * native_str = addr_app_to_native((uint32)(uintptr_t)str);
char * native_fmt = addr_app_to_native((uint32)(uintptr_t)format);
_va_list native_va_args = addr_app_to_native((uint32)(uintptr_t)va_args);
ctx.str = native_str;
ctx.max = size;
ctx.count = 0;
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, format, va_args,
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, native_fmt, native_va_args,
module_inst))
return 0;
if (ctx.count < ctx.max) {
str[ctx.count] = '\0';
native_str[ctx.count] = '\0';
}
return (int)ctx.count;
@ -540,7 +576,13 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
static int
puts_wrapper(wasm_exec_env_t exec_env, const char *str)
{
return os_printf("%s\n", str);
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)str))
return -1;
char * native_str = addr_app_to_native((uint32)(uintptr_t)str);
return os_printf("%s\n", native_str);
}
static int
@ -553,18 +595,23 @@ putchar_wrapper(wasm_exec_env_t exec_env, int c)
static uint32
strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *str_ret;
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
char *str_ret = 0;
uint32 len;
uint32 str_ret_offset = 0;
if (!validate_app_str_addr((uint32)(uintptr_t)str))
return 0;
char * native_str = addr_app_to_native((uint32)(uintptr_t)str);
/* str has been checked by runtime */
if (str) {
len = (uint32)strlen(str) + 1;
if (native_str) {
len = (uint32)strlen(native_str) + 1;
str_ret_offset = module_malloc(len, (void **)&str_ret);
if (str_ret_offset) {
bh_memcpy_s(str_ret, len, str, len);
bh_memcpy_s(str_ret, len, native_str, len);
}
}
@ -583,11 +630,16 @@ memcmp_wrapper(wasm_exec_env_t exec_env, const void *s1, const void *s2,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* s2 has been checked by runtime */
if (!validate_native_addr((void *)s1, size))
if (!validate_app_addr((uint32)(uintptr_t)s1, size))
return 0;
return memcmp(s1, s2, size);
if (!validate_app_addr((uint32)(uintptr_t)s2, size))
return 0;
void * native_s1 = addr_app_to_native((uint32)(uintptr_t)s1);
void * native_s2 = addr_app_to_native((uint32)(uintptr_t)s2);
return memcmp(native_s1, native_s2, size);
}
static uint32
@ -595,47 +647,55 @@ memcpy_wrapper(wasm_exec_env_t exec_env, void *dst, const void *src,
uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst);
if (size == 0)
return dst_offset;
return (uint32)(uintptr_t)dst;
/* src has been checked by runtime */
if (!validate_native_addr(dst, size))
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)src, size))
return (uint32)(uintptr_t)dst;
bh_memcpy_s(dst, size, src, size);
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return (uint32)(uintptr_t)dst;
void * native_src = addr_app_to_native((uint32)(uintptr_t)src);
void * native_dst = addr_app_to_native((uint32)(uintptr_t)dst);
bh_memcpy_s(native_dst, size, native_src, size);
return (uint32)(uintptr_t)dst;
}
static uint32
memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst);
if (size == 0)
return dst_offset;
return (uint32)(uintptr_t)dst;
/* src has been checked by runtime */
if (!validate_native_addr(dst, size))
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)src, size))
return (uint32)(uintptr_t)dst;
memmove(dst, src, size);
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return (uint32)(uintptr_t)dst;
void * native_src = addr_app_to_native((uint32)(uintptr_t)src);
void * native_dst = addr_app_to_native((uint32)(uintptr_t)dst);
memmove(native_dst, native_src, size);
return (uint32)(uintptr_t)dst;
}
static uint32
memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 s_offset = addr_native_to_app(s);
if (!validate_native_addr(s, size))
return s_offset;
if (!validate_app_addr((uint32)(uintptr_t)s, size))
return (uint32)(uintptr_t)s;
memset(s, c, size);
return s_offset;
void * native_s = addr_app_to_native((uint32)(uintptr_t)s);
memset(native_s, c, size);
return (uint32)(uintptr_t)s;
}
static uint32
@ -644,16 +704,30 @@ strchr_wrapper(wasm_exec_env_t exec_env, const char *s, int32 c)
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *ret;
if (!validate_app_str_addr((uint32)(uintptr_t)s))
return 0;
char * native_s = addr_app_to_native((uint32)(uintptr_t)s);
/* s has been checked by runtime */
ret = strchr(s, c);
ret = strchr(native_s, c);
return ret ? addr_native_to_app(ret) : 0;
}
static int32
strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)s1))
return 0;
if (!validate_app_str_addr((uint32)(uintptr_t)s2))
return 0;
char * native_s1 = addr_app_to_native((uint32)(uintptr_t)s1);
char * native_s2 = addr_app_to_native((uint32)(uintptr_t)s2);
/* s1 and s2 have been checked by runtime */
return strcmp(s1, s2);
return strcmp(native_s1, native_s2);
}
static int32
@ -662,29 +736,43 @@ strncmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* s2 has been checked by runtime */
if (!validate_native_addr((void *)s1, size))
if (!validate_app_addr((uint32)(uintptr_t)s1, size))
return 0;
return strncmp(s1, s2, size);
/* s2 has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)s2, size))
return 0;
char * native_s1 = addr_app_to_native((uint32)(uintptr_t)s1);
char * native_s2 = addr_app_to_native((uint32)(uintptr_t)s2);
return strncmp(native_s1, native_s2, size);
}
static uint32
strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 len = (uint32)strlen(src) + 1;
/* src has been checked by runtime */
if (!validate_native_addr(dst, len))
if (!validate_app_str_addr((uint32)(uintptr_t)src))
return 0;
char * native_src = addr_app_to_native((uint32)(uintptr_t)src);
uint32 len = (uint32)strlen(native_src) + 1;
/* src has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)dst, len))
return 0;
char * native_dst = addr_app_to_native((uint32)(uintptr_t)dst);
#ifndef BH_PLATFORM_WINDOWS
strncpy(dst, src, len);
strncpy(native_dst, native_src, len);
#else
strncpy_s(dst, len, src, len);
strncpy_s(native_dst, len, native_src, len);
#endif
return addr_native_to_app(dst);
return (uint32)(uintptr_t)dst;
}
static uint32
@ -693,36 +781,47 @@ strncpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* src has been checked by runtime */
if (!validate_native_addr(dst, size))
if (!validate_app_addr((uint32)(uintptr_t)src, size))
return 0;
/* src has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return 0;
void * native_src = addr_app_to_native((uint32)(uintptr_t)src);
void * native_dst = addr_app_to_native((uint32)(uintptr_t)dst);
#ifndef BH_PLATFORM_WINDOWS
strncpy(dst, src, size);
strncpy(native_dst, native_src, size);
#else
strncpy_s(dst, size, src, size);
strncpy_s(native_dst, size, native_src, size);
#endif
return addr_native_to_app(dst);
return (uint32)(uintptr_t)dst;
}
static uint32
strlen_wrapper(wasm_exec_env_t exec_env, const char *s)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)s))
return 0;
char * native_str = addr_app_to_native((uint32)(uintptr_t)s);
/* s has been checked by runtime */
return (uint32)strlen(s);
return (uint32)strlen(native_str);
}
static uint32
malloc_wrapper(wasm_exec_env_t exec_env, uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
return module_malloc(size, NULL);
}
static uint32
calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
uint64 total_size = (uint64)nmemb * (uint64)size;
uint32 ret_offset = 0;
uint8 *ret_ptr;
@ -741,7 +840,7 @@ calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size)
static uint32
realloc_wrapper(wasm_exec_env_t exec_env, uint32 ptr, uint32 new_size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
return wasm_runtime_module_realloc(module_inst, ptr, new_size, NULL);
}
@ -749,19 +848,25 @@ realloc_wrapper(wasm_exec_env_t exec_env, uint32 ptr, uint32 new_size)
static void
free_wrapper(wasm_exec_env_t exec_env, void *ptr)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
if (!validate_native_addr(ptr, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)ptr, sizeof(uint32)))
return;
module_free(addr_native_to_app(ptr));
module_free((uint32)(uintptr_t)ptr);
}
static int32
atoi_wrapper(wasm_exec_env_t exec_env, const char *s)
{
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
if (!validate_app_addr((uint32)(uintptr_t)s, 1))
return 0;
char * native_s = addr_app_to_native((uint32)(uintptr_t)s);
/* s has been checked by runtime */
return atoi(s);
return atoi(native_s);
}
static void
@ -780,12 +885,18 @@ strtol_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
wasm_module_inst_t module_inst = get_module_inst(exec_env);
int32 num = 0;
/* nptr has been checked by runtime */
if (!validate_native_addr(endptr, sizeof(uint32)))
if (!validate_app_str_addr((uint32)(uintptr_t)nptr))
return 0;
num = (int32)strtol(nptr, endptr, base);
*(uint32 *)endptr = addr_native_to_app(*endptr);
/* nptr has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)endptr, sizeof(uint32)))
return 0;
char * native_nptr = addr_app_to_native((uint32)(uintptr_t)nptr);
char ** native_endptr = addr_app_to_native((uint32)(uintptr_t)endptr);
num = (int32)strtol(native_nptr, native_endptr, base);
*(uint32 *)native_endptr = addr_native_to_app(*native_endptr);
return num;
}
@ -797,26 +908,57 @@ strtoul_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr,
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 num = 0;
/* nptr has been checked by runtime */
if (!validate_native_addr(endptr, sizeof(uint32)))
if (!validate_app_str_addr((uint32)(uintptr_t)nptr))
return 0;
num = (uint32)strtoul(nptr, endptr, base);
*(uint32 *)endptr = addr_native_to_app(*endptr);
/* nptr has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)endptr, sizeof(uint32)))
return 0;
char * native_nptr = addr_app_to_native((uint32)(uintptr_t)nptr);
char ** native_endptr = addr_app_to_native((uint32)(uintptr_t)endptr);
num = (uint32)strtoul(native_nptr, native_endptr, base);
*(uint32 *)native_endptr = addr_native_to_app(*native_endptr);
return num;
}
static double
strtod_wrapper(wasm_exec_env_t exec_env, const char *nptr, char **endptr)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
double num = 0.0;
if (!validate_app_str_addr((uint32)(uintptr_t)nptr))
return 0;
/* nptr has been checked by runtime */
if (!validate_app_addr((uint32)(uintptr_t)endptr, sizeof(double)))
return 0;
char * native_nptr = addr_app_to_native((uint32)(uintptr_t)nptr);
char ** native_endptr = addr_app_to_native((uint32)(uintptr_t)endptr);
num = strtod(native_nptr, native_endptr);
*(uint32 *)native_endptr = addr_native_to_app(*native_endptr);
return num;
}
static uint32
memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
void *res;
void *res = NULL;
if (!validate_native_addr((void *)s, n))
if (!validate_app_addr((uint32)(uintptr_t)s, n))
return 0;
res = memchr(s, c, n);
void * native_s = addr_app_to_native((uint32)(uintptr_t)s);
res = memchr(native_s, c, n);
return addr_native_to_app(res);
}
@ -824,30 +966,71 @@ static int32
strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
uint32 n)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_addr((uint32)(uintptr_t)s1, n))
return 0;
if (!validate_app_addr((uint32)(uintptr_t)s2, n))
return 0;
void * native_s1 = addr_app_to_native((uint32)(uintptr_t)s1);
void * native_s2 = addr_app_to_native((uint32)(uintptr_t)s2);
/* s1 and s2 have been checked by runtime */
return strncasecmp(s1, s2, n);
return strncasecmp(native_s1, native_s2, n);
}
static uint32
strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)s))
return 0;
if (!validate_app_str_addr((uint32)(uintptr_t)accept))
return 0;
char * native_s = addr_app_to_native((uint32)(uintptr_t)s);
char * native_accept = addr_app_to_native((uint32)(uintptr_t)accept);
/* s and accept have been checked by runtime */
return (uint32)strspn(s, accept);
return (uint32)strspn(native_s, native_accept);
}
static uint32
strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)s))
return 0;
if (!validate_app_str_addr((uint32)(uintptr_t)reject))
return 0;
char * native_s = addr_app_to_native((uint32)(uintptr_t)s);
char * native_reject = addr_app_to_native((uint32)(uintptr_t)reject);
/* s and reject have been checked by runtime */
return (uint32)strcspn(s, reject);
return (uint32)strcspn(native_s, native_reject);
}
static uint32
strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)s))
return 0;
if (!validate_app_str_addr((uint32)(uintptr_t)find))
return 0;
char * native_s = addr_app_to_native((uint32)(uintptr_t)s);
char * native_find = addr_app_to_native((uint32)(uintptr_t)find);
/* s and find have been checked by runtime */
char *res = strstr(s, find);
char *res = strstr(native_s, native_find);
return addr_native_to_app(res);
}
@ -884,7 +1067,8 @@ isprint_wrapper(wasm_exec_env_t exec_env, int32 c)
static int32
isdigit_wrapper(wasm_exec_env_t exec_env, int32 c)
{
return isdigit(c);
return c;
//return isdigit(c);
}
static int32
@ -905,6 +1089,37 @@ toupper_wrapper(wasm_exec_env_t exec_env, int32 c)
return toupper(c);
}
static
uint32 libc_wasm_tolower_loc = 0;
static uint32
__ctype_tolower_loc_wrapper(wasm_exec_env_t exec_env)
{
const int32 ** native_tolower_loc = NULL;
int * wasm_tolower_loc_native = NULL;
uint32 wasm_tolower_loc = libc_wasm_tolower_loc;
uint32 program_wasm_tolower_loc = 0;
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
program_wasm_tolower_loc = wasm_program_get_ctype_tolower_mem(module_inst);
#endif
if (program_wasm_tolower_loc)
wasm_tolower_loc = program_wasm_tolower_loc;
if (!wasm_tolower_loc) {
wasm_tolower_loc = module_malloc(sizeof(int32) * 384, (void**)&wasm_tolower_loc_native);
native_tolower_loc = __ctype_tolower_loc();
bh_memcpy_s(wasm_tolower_loc_native, sizeof(int32) * 384, *native_tolower_loc, sizeof(int32) * 384);
#if WASM_ENABLE_DYNAMIC_LINKING != 0
wasm_program_set_ctype_tolower_mem(module_inst, wasm_tolower_loc);
#endif
libc_wasm_tolower_loc = wasm_tolower_loc;
}
return wasm_tolower_loc;
}
static int32
isalnum_wrapper(wasm_exec_env_t exec_env, int32 c)
{
@ -997,21 +1212,44 @@ emscripten_memcpy_big_wrapper(wasm_exec_env_t exec_env, void *dst,
const void *src, uint32 size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst);
/* src has been checked by runtime */
if (!validate_native_addr(dst, size))
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)src, size))
return 0;
bh_memcpy_s(dst, size, src, size);
return dst_offset;
if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return 0;
void * native_src = addr_app_to_native((uint32)(uintptr_t)src);
void * native_dst = addr_app_to_native((uint32)(uintptr_t)dst);
bh_memcpy_s(native_dst, size, native_src, size);
return (uint32)(uintptr_t)dst;
}
static void
abort_ASwrapper(wasm_exec_env_t exec_env, const char * msg, const char * file, int line, int column)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)msg))
return;
if (!validate_app_str_addr((uint32)(uintptr_t)file))
return;
char * native_msg = addr_app_to_native((uint32)(uintptr_t)msg);
char * native_file = addr_app_to_native((uint32)(uintptr_t)file);
char buf[128] = "";
snprintf(buf, sizeof(buf), "env.abort(%s @%s:%d:%d)", native_msg, native_file, line, column);
wasm_runtime_set_exception(module_inst, buf);
}
static void
abort_wrapper(wasm_exec_env_t exec_env, int32 code)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char buf[32];
char buf[32] = "";
snprintf(buf, sizeof(buf), "env.abort(%i)", code);
wasm_runtime_set_exception(module_inst, buf);
}
@ -1020,7 +1258,7 @@ static void
abortStackOverflow_wrapper(wasm_exec_env_t exec_env, int32 code)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char buf[32];
char buf[32] = "";
snprintf(buf, sizeof(buf), "env.abortStackOverflow(%i)", code);
wasm_runtime_set_exception(module_inst, buf);
}
@ -1029,7 +1267,7 @@ static void
nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char buf[32];
char buf[32] = "";
snprintf(buf, sizeof(buf), "env.nullFunc_X(%i)", code);
wasm_runtime_set_exception(module_inst, buf);
}
@ -1037,7 +1275,7 @@ nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code)
static uint32
__cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
uint32 exception = module_malloc(thrown_size, NULL);
if (!exception)
return 0;
@ -1054,7 +1292,7 @@ __cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
void *tinfo, uint32 table_elem_idx)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char buf[32];
char buf[32] = "";
snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
wasm_runtime_set_exception(module_inst, buf);
@ -1072,12 +1310,14 @@ clock_gettime_wrapper(wasm_exec_env_t exec_env, uint32 clk_id,
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint64 time;
if (!validate_native_addr(ts_app, sizeof(struct timespec_app)))
if (!validate_app_addr((uint32)(uintptr_t)ts_app, sizeof(struct timespec_app)))
return (uint32)-1;
struct timespec_app * native_ts_app = addr_app_to_native((uint32)(uintptr_t)ts_app);
time = os_time_get_boot_microsecond();
ts_app->tv_sec = time / 1000000;
ts_app->tv_nsec = (time % 1000000) * 1000;
native_ts_app->tv_sec = time / 1000000;
native_ts_app->tv_nsec = (time % 1000000) * 1000;
return (uint32)0;
}
@ -1090,6 +1330,57 @@ clock_wrapper(wasm_exec_env_t exec_env)
return os_time_get_boot_microsecond() * 1000;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static uint32
dlopen_wrapper(wasm_exec_env_t exec_env,
const char * path, uint32 flags)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)path))
return 0;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
//printf("hello open\n");
return wasm_program_open_dependencies(module_inst, native_path);
}
static uint32
dlsym_wrapper(wasm_exec_env_t exec_env,
uint32 handle, const char * symbol_name)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_str_addr((uint32)(uintptr_t)symbol_name))
return 0;
char * native_name = addr_app_to_native((uint32)(uintptr_t)symbol_name);
//printf("hello dlsym\n");
return wasm_program_lookup_symbol_from_module(module_inst, (uint32)handle, native_name);
}
#if 0
static uint32
dltest_wrapper(wasm_exec_env_t exec_env, uint32 handle)
{
return handle;
}
#endif
static uint32
dlclose_wrapper(wasm_exec_env_t exec_env, uint32 handle)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
//printf("hello dlclose\n");
wasm_program_close_dependencies(module_inst, handle);
return 0;
}
#endif
#if WASM_ENABLE_SPEC_TEST != 0
static void
print_wrapper(wasm_exec_env_t exec_env)
@ -1130,10 +1421,14 @@ print_f64_wrapper(wasm_exec_env_t exec_env, double f64)
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL }
{ (NATIVE_SYMBOL_U)(uint32)WAMR_CSP_##func_name, func_name##_wrapper, signature, NULL }
#define REG_AS_NATIVE_FUNC(func_name, signature) \
{ (NATIVE_SYMBOL_U)(uint32)WAMR_CSP_##func_name, func_name##_ASwrapper, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(iprintf, "($*)i"),
REG_NATIVE_FUNC(printf, "($*)i"),
REG_NATIVE_FUNC(sprintf, "($$*)i"),
REG_NATIVE_FUNC(snprintf, "(*~$*)i"),
@ -1160,6 +1455,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(exit, "(i)"),
REG_NATIVE_FUNC(strtol, "($*i)i"),
REG_NATIVE_FUNC(strtoul, "($*i)i"),
REG_NATIVE_FUNC(strtod, "($*)F"),
REG_NATIVE_FUNC(memchr, "(*ii)i"),
REG_NATIVE_FUNC(strncasecmp, "($$i)"),
REG_NATIVE_FUNC(strspn, "($$)i"),
@ -1174,6 +1470,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(isxdigit, "(i)i"),
REG_NATIVE_FUNC(tolower, "(i)i"),
REG_NATIVE_FUNC(toupper, "(i)i"),
REG_NATIVE_FUNC(__ctype_tolower_loc, "()i"),
REG_NATIVE_FUNC(isalnum, "(i)i"),
REG_NATIVE_FUNC(setTempRet0, "(i)"),
REG_NATIVE_FUNC(getTempRet0, "()i"),
@ -1185,6 +1482,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(llvm_stacksave, "()i"),
REG_NATIVE_FUNC(emscripten_memcpy_big, "(**~)i"),
REG_NATIVE_FUNC(abort, "(i)"),
REG_AS_NATIVE_FUNC(abort, "($$ii)"),
REG_NATIVE_FUNC(abortStackOverflow, "(i)"),
REG_NATIVE_FUNC(nullFunc_X, "(i)"),
REG_NATIVE_FUNC(__cxa_allocate_exception, "(i)i"),
@ -1192,6 +1490,12 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(__cxa_throw, "(**i)"),
REG_NATIVE_FUNC(clock_gettime, "(i*)i"),
REG_NATIVE_FUNC(clock, "()I"),
#if WASM_ENABLE_DYNAMIC_LINKING != 0
REG_NATIVE_FUNC(dlopen, "($i)i"),
REG_NATIVE_FUNC(dlsym, "(i$)i"),
//REG_NATIVE_FUNC(dltest, "(i)i"),
REG_NATIVE_FUNC(dlclose, "(i)i"),
#endif
};
#if WASM_ENABLE_SPEC_TEST != 0

View File

@ -15,6 +15,9 @@
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
#define get_root_module_inst(exec_env) \
wasm_runtime_get_root_module_inst(exec_env)
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
@ -224,7 +227,7 @@ static int
mmap_wrapper(wasm_exec_env_t exec_env, void *addr, int length, int prot,
int flags, int fd, int64 offset)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
uint32 buf_offset;
char *buf;
int size_read;

View File

@ -1076,7 +1076,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, wasi_##func_name, signature, NULL }
{ (NATIVE_SYMBOL_U)(uint32)WAMR_CSP_##func_name, wasi_##func_name, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = {

View File

@ -5,6 +5,7 @@
#include "libc_wasi_wrapper.h"
#include "bh_platform.h"
#include "ConstStrDesc.h"
#include "wasm_export.h"
void
@ -104,25 +105,30 @@ wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
total_size = sizeof(int32) * ((uint64)argc + 1);
if (total_size >= UINT32_MAX
|| !validate_native_addr(argv_offsets, (uint32)total_size)
|| !validate_app_addr((uint32)(intptr_t)argv_offsets, (uint32)total_size)
|| argv_buf_size >= UINT32_MAX
|| !validate_native_addr(argv_buf, (uint32)argv_buf_size))
|| !validate_app_addr((uint32)(intptr_t)argv_buf, (uint32)argv_buf_size))
return (wasi_errno_t)-1;
total_size = sizeof(char *) * ((uint64)argc + 1);
if (total_size >= UINT32_MAX
|| !(argv = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_args_get(argv_environ, argv, argv_buf);
char * native_argv_buf = addr_app_to_native((uint32)(intptr_t)argv_buf);
err = wasmtime_ssp_args_get(argv_environ, argv, native_argv_buf);
if (err) {
wasm_runtime_free(argv);
return err;
}
uint32 * native_argv_offsets = addr_app_to_native((uint32)(intptr_t)argv_offsets);
for (i = 0; i < argc; i++)
argv_offsets[i] = addr_native_to_app(argv[i]);
argv_offsets[argc] = 0;
native_argv_offsets[i] = addr_native_to_app(argv[i]);
native_argv_offsets[argc] = 0;
wasm_runtime_free(argv);
return 0;
@ -141,8 +147,8 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(argc_app, sizeof(uint32))
|| !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
if (!validate_app_addr((uint32)(intptr_t)argc_app, sizeof(uint32))
|| !validate_app_addr((uint32)(intptr_t)argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1;
argv_environ = wasi_ctx->argv_environ;
@ -151,8 +157,10 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
if (err)
return err;
*argc_app = (uint32)argc;
*argv_buf_size_app = (uint32)argv_buf_size;
uint32 * native_argc_app = addr_app_to_native((uint32)(intptr_t)argc_app);
uint32 * native_argv_buf_size_app = addr_app_to_native((uint32)(intptr_t)argv_buf_size_app);
*native_argc_app = (uint32)argc;
*native_argv_buf_size_app = (uint32)argv_buf_size;
return 0;
}
@ -163,10 +171,12 @@ wasi_clock_res_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
if (!validate_app_addr((uint32)(intptr_t)resolution, sizeof(wasi_timestamp_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_clock_res_get(clock_id, resolution);
wasi_timestamp_t * native_resolution = addr_app_to_native((uint32)(intptr_t)resolution);
return wasmtime_ssp_clock_res_get(clock_id, native_resolution);
}
static wasi_errno_t
@ -177,10 +187,12 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
if (!validate_app_addr((uint32)(intptr_t)time, sizeof(wasi_timestamp_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_clock_time_get(clock_id, precision, time);
wasi_timestamp_t * native_time = addr_app_to_native((uint32)(intptr_t)time);
return wasmtime_ssp_clock_time_get(clock_id, precision, native_time);
}
static wasi_errno_t
@ -206,9 +218,9 @@ wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
total_size = sizeof(int32) * ((uint64)environ_count + 1);
if (total_size >= UINT32_MAX
|| !validate_native_addr(environ_offsets, (uint32)total_size)
|| !validate_app_addr((uint32)(intptr_t)environ_offsets, (uint32)total_size)
|| environ_buf_size >= UINT32_MAX
|| !validate_native_addr(environ_buf, (uint32)environ_buf_size))
|| !validate_app_addr((uint32)(intptr_t)environ_buf, (uint32)environ_buf_size))
return (wasi_errno_t)-1;
total_size = sizeof(char *) * (((uint64)environ_count + 1));
@ -217,15 +229,18 @@ wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
|| !(environs = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_get(argv_environ, environs, environ_buf);
char * native_environ_buf = addr_app_to_native((uint32)(intptr_t)environ_buf);
err = wasmtime_ssp_environ_get(argv_environ, environs, native_environ_buf);
if (err) {
wasm_runtime_free(environs);
return err;
}
char * native_environ_offsets = addr_app_to_native((uint32)(intptr_t)environ_offsets);
for (i = 0; i < environ_count; i++)
environ_offsets[i] = addr_native_to_app(environs[i]);
environ_offsets[environ_count] = 0;
native_environ_offsets[i] = addr_native_to_app(environs[i]);
native_environ_offsets[environ_count] = 0;
wasm_runtime_free(environs);
return 0;
@ -245,8 +260,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(environ_count_app, sizeof(uint32))
|| !validate_native_addr(environ_buf_size_app, sizeof(uint32)))
if (!validate_app_addr((uint32)(intptr_t)environ_count_app, sizeof(uint32))
|| !validate_app_addr((uint32)(intptr_t)environ_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count,
@ -254,8 +269,11 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
if (err)
return err;
*environ_count_app = (uint32)environ_count;
*environ_buf_size_app = (uint32)environ_buf_size;
uint32 * native_environ_count_app = addr_app_to_native((uint32)(intptr_t)environ_count_app);
uint32 * native_environ_buf_size_app = addr_app_to_native((uint32)(intptr_t)environ_buf_size_app);
*native_environ_count_app = (uint32)environ_count;
*native_environ_buf_size_app = (uint32)environ_buf_size;
return 0;
}
@ -273,15 +291,17 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t)))
if (!validate_app_addr((uint32)(intptr_t)prestat_app, sizeof(wasi_prestat_app_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_prestat_get(prestats, fd, &prestat);
if (err)
return err;
prestat_app->pr_type = prestat.pr_type;
prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
wasi_prestat_app_t * native_prestat_app = addr_app_to_native((uint32)(intptr_t)prestat_app);
native_prestat_app->pr_type = prestat.pr_type;
native_prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
return 0;
}
@ -296,7 +316,12 @@ wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_prestat_dir_name(prestats, fd, path, path_len);
if (!validate_app_addr((uint32)(intptr_t)path, path_len))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(intptr_t)path);
return wasmtime_ssp_fd_prestat_dir_name(prestats, fd, native_path, path_len);
}
static wasi_errno_t
@ -343,9 +368,9 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
if (!validate_app_addr((uint32)(intptr_t)nread_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX
|| !validate_native_addr(iovec_app, (uint32)total_size))
|| !validate_app_addr((uint32)(intptr_t)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
@ -355,13 +380,15 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
iovec = iovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
for (i = 0; i < iovs_len; i++, native_iovec_app++, iovec++) {
if (!validate_app_addr(native_iovec_app->buf_offset, native_iovec_app->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
iovec->buf_len = iovec_app->buf_len;
iovec->buf = (void *)addr_app_to_native(native_iovec_app->buf_offset);
iovec->buf_len = native_iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset,
@ -369,7 +396,9 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
if (err)
goto fail;
*nread_app = (uint32)nread;
uint32 * native_nread_app = addr_app_to_native((uint32)(intptr_t)nread_app);
*native_nread_app = (uint32)nread;
/* success */
err = 0;
@ -397,9 +426,9 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
if (!validate_app_addr((uint32)(intptr_t)nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX
|| !validate_native_addr((void *)iovec_app, (uint32)total_size))
|| !validate_app_addr((uint32)(intptr_t)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -409,13 +438,15 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec = ciovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
for (i = 0; i < iovs_len; i++, native_iovec_app++, ciovec++) {
if (!validate_app_addr(native_iovec_app->buf_offset, native_iovec_app->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
ciovec->buf_len = iovec_app->buf_len;
ciovec->buf = (char *)addr_app_to_native(native_iovec_app->buf_offset);
ciovec->buf_len = native_iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset,
@ -423,7 +454,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (err)
goto fail;
*nwritten_app = (uint32)nwritten;
uint32 * native_nwritten_app = addr_app_to_native((uint32)(intptr_t)nwritten_app);
*native_nwritten_app = (uint32)nwritten;
/* success */
err = 0;
@ -450,9 +482,9 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
if (!validate_app_addr((uint32)(intptr_t)nread_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX
|| !validate_native_addr((void *)iovec_app, (uint32)total_size))
|| !validate_app_addr((uint32)(intptr_t)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
@ -462,20 +494,23 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
iovec = iovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
for (i = 0; i < iovs_len; i++, native_iovec_app++, iovec++) {
if (!validate_app_addr(native_iovec_app->buf_offset, native_iovec_app->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
iovec->buf_len = iovec_app->buf_len;
iovec->buf = (void *)addr_app_to_native(native_iovec_app->buf_offset);
iovec->buf_len = native_iovec_app->buf_len;
}
err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread);
if (err)
goto fail;
*nread_app = (uint32)nread;
uint32 * native_nread_app = addr_app_to_native((uint32)(intptr_t)nread_app);
*native_nread_app = (uint32)nread;
/* success */
err = 0;
@ -510,10 +545,11 @@ wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
if (!validate_app_addr((uint32)(intptr_t)newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset);
wasi_filesize_t * native_newoffset = addr_app_to_native((uint32)(intptr_t)newoffset);
return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, native_newoffset);
}
static wasi_errno_t
@ -526,10 +562,12 @@ wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
if (!validate_app_addr((uint32)(intptr_t)newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_tell(curfds, fd, newoffset);
wasi_filesize_t * native_newoffset = addr_app_to_native((uint32)(intptr_t)newoffset);
return wasmtime_ssp_fd_tell(curfds, fd, native_newoffset);
}
static wasi_errno_t
@ -545,14 +583,16 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
if (!validate_app_addr((uint32)(intptr_t)fdstat_app, sizeof(wasi_fdstat_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat);
if (err)
return err;
memcpy(fdstat_app, &fdstat, sizeof(wasi_fdstat_t));
wasi_fdstat_t * native_fdstat_app = addr_app_to_native((uint32)(intptr_t)fdstat_app);
memcpy(native_fdstat_app, &fdstat, sizeof(wasi_fdstat_t));
return 0;
}
@ -617,9 +657,13 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
|| total_size >= UINT32_MAX
|| !validate_native_addr((void *)iovec_app, (uint32)total_size))
if (total_size >= UINT32_MAX)
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)nwritten_app, sizeof(uint32)))
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)iovec_app, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
@ -629,20 +673,23 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec = ciovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(uintptr_t)iovec_app);
uint32 * native_nwritten_app = addr_app_to_native((uint32)(uintptr_t)nwritten_app);
for (i = 0; i < iovs_len; i++, native_iovec_app++, ciovec++) {
if (!validate_app_addr(native_iovec_app->buf_offset, native_iovec_app->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
ciovec->buf_len = iovec_app->buf_len;
ciovec->buf = (char *)addr_app_to_native(native_iovec_app->buf_offset);
ciovec->buf_len = native_iovec_app->buf_len;
}
err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten);
if (err)
goto fail;
*nwritten_app = (uint32)nwritten;
*native_nwritten_app = (uint32)nwritten;
/* success */
err = 0;
@ -691,7 +738,12 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len);
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
return wasmtime_ssp_path_create_directory(curfds, fd, native_path, path_len);
}
static wasi_errno_t
@ -708,8 +760,17 @@ wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path,
old_path_len, new_fd, new_path, new_path_len);
if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)new_path, new_path_len))
return (wasi_errno_t)-1;
char * native_old_path = addr_app_to_native((uint32)(uintptr_t)old_path);
char * native_new_path = addr_app_to_native((uint32)(uintptr_t)new_path);
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, native_old_path,
old_path_len, new_fd, native_new_path, new_path_len);
}
static wasi_errno_t
@ -728,14 +789,20 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len,
if (!validate_app_addr((uint32)(uintptr_t)fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, native_path, path_len,
oflags, fs_rights_base, fs_rights_inheriting,
fs_flags, &fd);
*fd_app = fd;
wasi_fd_t * native_fd_app = addr_app_to_native((uint32)(uintptr_t)fd_app);
*native_fd_app = fd;
return err;
}
@ -752,14 +819,21 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)buf, buf_len))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused);
if (!validate_app_addr((uint32)(uintptr_t)bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
void * native_buf = addr_app_to_native((uint32)(uintptr_t)buf);
err = wasmtime_ssp_fd_readdir(curfds, fd, native_buf, buf_len, cookie, &bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
uint32 * native_bufused_app = addr_app_to_native((uint32)(uintptr_t)bufused_app);
*native_bufused_app = (uint32)bufused;
return 0;
}
@ -777,15 +851,26 @@ wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len,
if (!validate_app_addr((uint32)(uintptr_t)buf, buf_len))
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
void * native_buf = addr_app_to_native((uint32)(uintptr_t)buf);
err = wasmtime_ssp_path_readlink(curfds, fd, native_path, path_len, native_buf, buf_len,
&bufused);
if (err)
return err;
*bufused_app = (uint32)bufused;
uint32 * native_bufused_app = addr_app_to_native((uint32)(uintptr_t)bufused_app);
*native_bufused_app = (uint32)bufused;
return 0;
}
@ -801,8 +886,17 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len,
new_fd, new_path, new_path_len);
if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)new_path, new_path_len))
return (wasi_errno_t)-1;
char * native_old_path = addr_app_to_native((uint32)(uintptr_t)old_path);
char * native_new_path = addr_app_to_native((uint32)(uintptr_t)new_path);
return wasmtime_ssp_path_rename(curfds, old_fd, native_old_path, old_path_len,
new_fd, native_new_path, new_path_len);
}
static wasi_errno_t
@ -816,10 +910,12 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
if (!validate_app_addr((uint32)(uintptr_t)filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat);
wasi_filestat_t * native_filestat = addr_app_to_native((uint32)(uintptr_t)filestat);
return wasmtime_ssp_fd_filestat_get(curfds, fd, native_filestat);
}
static wasi_errno_t
@ -864,11 +960,17 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len,
filestat);
if (!validate_app_addr((uint32)(uintptr_t)filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
wasi_filestat_t * native_filestat = addr_app_to_native((uint32)(uintptr_t)filestat);
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, native_path, path_len,
native_filestat);
}
static wasi_errno_t
@ -884,8 +986,13 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
return wasmtime_ssp_path_filestat_set_times(
curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags);
curfds, fd, flags, native_path, path_len, st_atim, st_mtim, fstflags);
}
static wasi_errno_t
@ -901,8 +1008,17 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len,
fd, new_path, new_path_len);
if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
return (wasi_errno_t)-1;
if (!validate_app_addr((uint32)(uintptr_t)new_path, new_path_len))
return (wasi_errno_t)-1;
char * native_old_path = addr_app_to_native((uint32)(uintptr_t)old_path);
char * native_new_path = addr_app_to_native((uint32)(uintptr_t)new_path);
return wasmtime_ssp_path_symlink(curfds, prestats, native_old_path, old_path_len,
fd, native_new_path, new_path_len);
}
static wasi_errno_t
@ -916,7 +1032,12 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len);
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
return wasmtime_ssp_path_unlink_file(curfds, fd, native_path, path_len);
}
static wasi_errno_t
@ -930,7 +1051,12 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
if (!validate_app_addr((uint32)(uintptr_t)path, path_len))
return (wasi_errno_t)-1;
char * native_path = addr_app_to_native((uint32)(uintptr_t)path);
return wasmtime_ssp_path_remove_directory(curfds, fd, native_path, path_len);
}
static wasi_errno_t
@ -946,16 +1072,20 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
if (!wasi_ctx)
return (wasi_errno_t)-1;
if (!validate_native_addr((void *)in, sizeof(wasi_subscription_t))
|| !validate_native_addr(out, sizeof(wasi_event_t))
|| !validate_native_addr(nevents_app, sizeof(uint32)))
if (!validate_app_addr((uint32)(uintptr_t)in, sizeof(wasi_subscription_t))
|| !validate_app_addr((uint32)(uintptr_t)out, sizeof(wasi_event_t))
|| !validate_app_addr((uint32)(uintptr_t)nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
wasi_subscription_t * native_in = addr_app_to_native((uint32)(uintptr_t)in);
wasi_event_t * native_out = addr_app_to_native((uint32)(uintptr_t)out);
err = wasmtime_ssp_poll_oneoff(curfds, native_in, native_out, nsubscriptions, &nevents);
if (err)
return err;
*nevents_app = (uint32)nevents;
uint32 * native_events_app = addr_app_to_native((uint32)(uintptr_t)nevents_app);
*native_events_app = (uint32)nevents;
return 0;
}
@ -983,7 +1113,12 @@ wasi_proc_raise(wasm_exec_env_t exec_env, wasi_signal_t sig)
static wasi_errno_t
wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
{
return wasmtime_ssp_random_get(buf, buf_len);
wasm_module_inst_t module_inst = get_module_inst(exec_env);
if (!validate_app_addr((uint32)(uintptr_t)buf, buf_len))
return (wasi_errno_t)-1;
void * native_buf = addr_app_to_native((uint32)(uintptr_t)buf);
return wasmtime_ssp_random_get(native_buf, buf_len);
}
static wasi_errno_t
@ -1004,10 +1139,10 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
if (!validate_native_addr(ro_datalen_app, (uint32)sizeof(uint32))
|| !validate_native_addr(ro_flags, (uint32)sizeof(wasi_roflags_t))
if (!validate_app_addr((uint32)(uintptr_t)ro_datalen_app, (uint32)sizeof(uint32))
|| !validate_app_addr((uint32)(uintptr_t)ro_flags, (uint32)sizeof(wasi_roflags_t))
|| total_size >= UINT32_MAX
|| !validate_native_addr(ri_data, (uint32)total_size))
|| !validate_app_addr((uint32)(uintptr_t)ri_data, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)ri_data_len;
@ -1017,21 +1152,25 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
iovec = iovec_begin;
for (i = 0; i < ri_data_len; i++, ri_data++, iovec++) {
if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
iovec_app_t * native_ri_data = addr_app_to_native((uint32)(uintptr_t)ri_data);
for (i = 0; i < ri_data_len; i++, native_ri_data++, iovec++) {
if (!validate_app_addr(native_ri_data->buf_offset, native_ri_data->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset);
iovec->buf_len = ri_data->buf_len;
iovec->buf = (void *)addr_app_to_native(native_ri_data->buf_offset);
iovec->buf_len = native_ri_data->buf_len;
}
wasi_roflags_t * native_ro_flags = addr_app_to_native((uint32)(uintptr_t)ro_flags);
err = wasmtime_ssp_sock_recv(curfds, sock, iovec_begin, ri_data_len,
ri_flags, &ro_datalen, ro_flags);
ri_flags, &ro_datalen, native_ro_flags);
if (err)
goto fail;
*(uint32 *)ro_datalen_app = (uint32)ro_datalen;
uint32 * native_ro_datalen_app = addr_app_to_native((uint32)(uintptr_t)ro_datalen_app);
*(uint32 *)native_ro_datalen_app = (uint32)ro_datalen;
/* success */
err = 0;
@ -1059,9 +1198,9 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
if (!validate_native_addr(so_datalen_app, sizeof(uint32))
if (!validate_app_addr((uint32)(uintptr_t)so_datalen_app, sizeof(uint32))
|| total_size >= UINT32_MAX
|| !validate_native_addr((void *)si_data, (uint32)total_size))
|| !validate_app_addr((uint32)(uintptr_t)si_data, (uint32)total_size))
return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
@ -1071,13 +1210,15 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
ciovec = ciovec_begin;
for (i = 0; i < si_data_len; i++, si_data++, ciovec++) {
if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
iovec_app_t * native_si_data = addr_app_to_native((uint32)(uintptr_t)si_data);
for (i = 0; i < si_data_len; i++, native_si_data++, ciovec++) {
if (!validate_app_addr(native_si_data->buf_offset, native_si_data->buf_len)) {
err = (wasi_errno_t)-1;
goto fail;
}
ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset);
ciovec->buf_len = si_data->buf_len;
ciovec->buf = (char *)addr_app_to_native(native_si_data->buf_offset);
ciovec->buf_len = native_si_data->buf_len;
}
err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len,
@ -1085,7 +1226,9 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
if (err)
goto fail;
*so_datalen_app = (uint32)so_datalen;
uint32 * native_so_datalen_app = addr_app_to_native((uint32)(uintptr_t)so_datalen_app);
*native_so_datalen_app = (uint32)so_datalen;
/* success */
err = 0;
@ -1116,7 +1259,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, wasi_##func_name, signature, NULL }
{ (NATIVE_SYMBOL_U)(uint32)WAMR_CSP_##func_name, wasi_##func_name, signature, NULL }
/* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = {

View File

@ -73,6 +73,57 @@ bh_hash_map_create(uint32 size, bool use_lock, HashFunc hash_func,
return map;
}
bool
bh_hash_map_insert_with_dup(HashMap *map, void *key, void *value)
{
uint32 index;
HashMapElem *elem;
if (!map || !key) {
LOG_ERROR("HashMap insert elem failed: map or key is NULL.\n");
return false;
}
if (map->lock) {
os_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
elem = map->elements[index];
while (elem) {
if (map->key_equal_func(elem->key, key)) {
if (elem->value == value)
break;
else
return false;
}
elem = elem->next;
}
if (!elem) {
if (!(elem = BH_MALLOC(sizeof(HashMapElem)))) {
LOG_ERROR("HashMap insert elem failed: alloc memory failed.\n");
goto fail;
}
elem->key = key;
elem->value = value;
elem->next = map->elements[index];
map->elements[index] = elem;
}
if (map->lock) {
os_mutex_unlock(map->lock);
}
return true;
fail:
if (map->lock) {
os_mutex_unlock(map->lock);
}
return false;
}
bool
bh_hash_map_insert(HashMap *map, void *key, void *value)
{

View File

@ -69,6 +69,20 @@ bh_hash_map_create(uint32 size, bool use_lock, HashFunc hash_func,
bool
bh_hash_map_insert(HashMap *map, void *key, void *value);
/**
* Insert an element to the hash map
*
* @param map the hash map to insert element
* @key the key of the element
* @value the value of the element
*
* @return true if success, false otherwise
* Note: fail if key is NULL
* if duplicated, considered as success.
*/
bool
bh_hash_map_insert_with_dup(HashMap *map, void *key, void *value);
/**
* Find an element in the hash map
*

View File

@ -56,6 +56,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
}
*ret_size = file_size;
printf("Read file %s to buffer successfully\n", filename);
return buffer;
}
#else /* else of defined(_WIN32) || defined(_WIN32_) */
@ -107,6 +108,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
}
*ret_size = file_size;
printf("Read file %s to buffer successfully\n", filename);
return buffer;
}
#endif /* end of defined(_WIN32) || defined(_WIN32_) */

View File

@ -4,6 +4,7 @@
cmake_minimum_required (VERSION 2.8)
project (iwasm)
# set (CMAKE_VERBOSE_MAKEFILE 1)
set (WAMR_BUILD_PLATFORM "linux")
@ -55,6 +56,10 @@ if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
set (WAMR_BUILD_LIBC_BUILTIN 1)
endif ()
if (NOT DEFINED AS_HARDCODE_ABORT)
set (AS_HARDCODE_ABORT 0)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
# Enable libc wasi support by default
set (WAMR_BUILD_LIBC_WASI 1)
@ -70,6 +75,17 @@ if (NOT DEFINED WAMR_BUILD_MULTI_MODULE)
set (WAMR_BUILD_MULTI_MODULE 0)
endif ()
if (NOT DEFINED WAMR_BUILD_DYNAMIC_LINKING)
# Eanble dynamic linking
set (WAMR_BUILD_DYNAMIC_LINKING 0)
endif ()
if (WAMR_BUILD_DYNAMIC_LINKING EQUAL 1)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_MULTI_MODULE 0)
endif ()
if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
# Disable pthread library by default
set (WAMR_BUILD_LIB_PTHREAD 0)

View File

@ -19,6 +19,16 @@ static char **app_argv;
#define MODULE_PATH ("--module-path=")
/* clang-format off */
#if 0
#if AS_HARDCODE_ABORT != 0
static void as_abort(int msg, int file, int line, int column)
{
fprintf(stdout, "wamr: as_abort\r\n");
exit(1);
}
#endif
#endif
static int
print_help()
{
@ -36,6 +46,18 @@ print_help()
" that runs commands in the form of \"FUNC ARG...\"\n");
printf(" --xip Enable XIP (Execution In Place) mode to run AOT file\n"
" generated with \"--enable-indirect-mode\" flag\n");
#if WASM_ENABLE_DYNAMIC_LINKING != 0
printf(" --enable-dlopen=n Enable explictily dynamic module loading\n"
" n is a 5-bit bitmap, each bit indicates a feature\n"
" from bits[0] to bits[4], they are:\n"
" bind mode, currently always lazy binding\n"
" where memory allocator comes from, 0 - from builtin libc; 1 - from root module\n"
" if use table space to store module exports function, 0 - no; 1 - yes\n"
" if root module is a AS module, 0 - no; 1 - yes\n"
" if enable cache to save symbol resolve result, 0 - no; 1 - yes, currently not supported yet\n"
" e.g. n = 14 (0b1110), indicates memory from root module, lazy binding, root module is AS module and use table space\n");
printf(" --disable-auto-ext Disable automatically update ext name in AOT mode\n");
#endif
#if WASM_ENABLE_LIBC_WASI != 0
printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
printf(" to the program, for example:\n");
@ -44,7 +66,7 @@ print_help()
printf(" to the program, for example:\n");
printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
printf(" --module-path= Indicate a module search path. default is current\n"
" directory('./')\n");
#endif
@ -57,8 +79,36 @@ print_help()
#endif
return 1;
}
/* clang-format on */
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static void *
app_instance_program_main(wasm_program_t program, wasm_module_inst_t module_inst)
{
const char *exception;
if (program) {
wasm_application_execute_program_main(program, app_argc, app_argv);
if ((exception = wasm_runtime_get_program_exception(program)))
printf("%s\n", exception);
} else
{
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst)))
printf("%s\n", exception);
}
return NULL;
}
static void *
app_instance_program_func(wasm_program_t program, wasm_module_inst_t module_inst, const char *func_name)
{
if (program)
wasm_application_execute_program_func(program, func_name, app_argc - 1,
app_argv + 1);
else
wasm_application_execute_func(module_inst, func_name, app_argc - 1,
app_argv + 1);
return NULL;
}
#endif
static void *
app_instance_main(wasm_module_inst_t module_inst)
{
@ -120,6 +170,44 @@ split_string(char *str, int *count)
}
return res;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
static void *
app_instance_program_repl(wasm_program_t program, wasm_module_inst_t module_inst)
{
char *cmd = NULL;
size_t len = 0;
ssize_t n;
while ((printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) {
bh_assert(n > 0);
if (cmd[n - 1] == '\n') {
if (n == 1)
continue;
else
cmd[n - 1] = '\0';
}
if (!strcmp(cmd, "__exit__")) {
printf("exit repl mode\n");
break;
}
app_argv = split_string(cmd, &app_argc);
if (app_argv == NULL) {
LOG_ERROR("Wasm prepare param failed: split string failed.\n");
break;
}
if (app_argc != 0) {
if (program)
wasm_application_execute_program_func(program, app_argv[0],
app_argc - 1, app_argv + 1);
else
wasm_application_execute_func(module_inst, app_argv[0],
app_argc - 1, app_argv + 1);
}
free(app_argv);
}
free(cmd);
return NULL;
}
#endif
static void *
app_instance_repl(wasm_module_inst_t module_inst)
@ -182,7 +270,7 @@ static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
static char *
handle_module_path(const char *module_path)
{
@ -190,30 +278,77 @@ handle_module_path(const char *module_path)
return (strchr(module_path, '=')) + 1;
}
static char *module_search_path = ".";
static char * module_search_paths = NULL;
static bool
module_reader_callback(const char *module_name, uint8 **p_buffer,
uint32 *p_size)
{
const char *format = "%s/%s.wasm";
int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
+ strlen(".wasm") + 1;
char *wasm_file_name = BH_MALLOC(sz);
if (!wasm_file_name) {
#if WASM_ENABLE_DYNAMIC_LINKING != 0
const char * format = "/%s";
const char * format_with_path = "%s/%s";
#else
const char * format = "/%s.wasm";
const char * format_with_path = "%s/%s.wasm";
#endif
const char * search_path = module_search_paths;
char * file_full_path = NULL;
int path_len = 0, buf_size = 0;
*p_buffer = NULL;
*p_size = 0;
while (search_path) {
char * end = strchr(search_path, ':');
uint32 len = 0;
if (end)
len = end - search_path;
else
len = strlen(search_path);
path_len = len + strlen("/") + strlen(module_name) +
strlen(".wasm") + 1;
if (path_len > buf_size) {
if (file_full_path)
wasm_runtime_free(file_full_path);
buf_size = path_len;
file_full_path = BH_MALLOC(buf_size);
if (!file_full_path) {
return false;
}
}
snprintf(wasm_file_name, sz, format, module_search_path, module_name);
memset(file_full_path, 0, buf_size);
bh_memcpy_s(file_full_path, buf_size, search_path, len);
snprintf(file_full_path + len, buf_size - len, format, module_name);
*p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size);
*p_buffer = (uint8_t *)bh_read_file_to_buffer(file_full_path, p_size);
wasm_runtime_free(wasm_file_name);
return *p_buffer != NULL;
if (*p_buffer)
break;
if (end) {
search_path = end + 1;
continue;
}
search_path = NULL;
}
if (!search_path) {
bh_assert(!*p_buffer);
if (!file_full_path) {
buf_size = strlen("./") + strlen(module_name) +
strlen(".wasm") + 1;
file_full_path = BH_MALLOC(buf_size);
if (!file_full_path) {
return false;
}
}
snprintf(file_full_path, buf_size, format_with_path, ".", module_name);
*p_buffer = (uint8_t *)bh_read_file_to_buffer(file_full_path, p_size);
}
if (file_full_path)
wasm_runtime_free(file_full_path);
return (*p_buffer != NULL);
}
static void
moudle_destroyer(uint8 *buffer, uint32 size)
module_destroyer_impl(uint8 *buffer, uint32 size)
{
if (!buffer) {
return;
@ -228,6 +363,7 @@ int
main(int argc, char *argv[])
{
char *wasm_file = NULL;
const char * file_name = NULL;
const char *func_name = NULL;
uint8 *wasm_file_buf = NULL;
uint32 wasm_file_size;
@ -241,6 +377,11 @@ main(int argc, char *argv[])
#endif
bool is_repl_mode = false;
bool is_xip_mode = false;
bool is_standalone_mode = true;
bool auto_ext_name = true;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
uint32 dlopen_mode = 0; // lazy binding | from builtin libc
#endif
#if WASM_ENABLE_LIBC_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
@ -276,6 +417,17 @@ main(int argc, char *argv[])
else if (!strcmp(argv[0], "--xip")) {
is_xip_mode = true;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
else if (!strncmp(argv[0], "--enable-dlopen=", 16)) {
if (argv[0][16] == '\0')
return print_help();
is_standalone_mode = false;
dlopen_mode = atoi(argv[0] + 16);
}
else if (!strcmp(argv[0], "--disable-auto-ext")) {
auto_ext_name = false;
}
#endif
else if (!strncmp(argv[0], "--stack-size=", 13)) {
if (argv[0][13] == '\0')
return print_help();
@ -318,10 +470,10 @@ main(int argc, char *argv[])
}
}
#endif /* WASM_ENABLE_LIBC_WASI */
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
module_search_path = handle_module_path(argv[0]);
if (!strlen(module_search_path)) {
module_search_paths = handle_module_path(argv[0]);
if (!strlen(module_search_paths)) {
return print_help();
}
}
@ -358,6 +510,8 @@ main(int argc, char *argv[])
app_argv = argv;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.standalone = is_standalone_mode;
init_args.auto_ext_name = auto_ext_name;
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
init_args.mem_alloc_type = Alloc_With_Pool;
@ -377,6 +531,23 @@ main(int argc, char *argv[])
strcpy(init_args.ip_addr, ip_addr);
#endif
#if 0
#if AS_HARDCODE_ABORT != 0
static NativeSymbol native_symbols[] =
{
{
{"abort"}, // the name of WASM function name
as_abort, // the native function pointer
"(iiii)", // the function prototype signature, avoid to use i32
NULL // attachment is NULL
}
};
init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
init_args.native_module_name = "env";
init_args.native_symbols = native_symbols;
#endif
#endif
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime environment failed.\n");
@ -411,15 +582,50 @@ main(int argc, char *argv[])
}
#if WASM_ENABLE_MULTI_MODULE != 0
wasm_runtime_set_module_reader(module_reader_callback, moudle_destroyer);
wasm_runtime_set_module_reader(module_reader_callback, module_destroyer_impl);
#endif
file_name = strrchr(wasm_file, '/');
if (file_name)
file_name ++;
else
file_name = wasm_file;
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
if (!(wasm_module = wasm_runtime_load2(file_name, wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail2;
}
#if WASM_ENABLE_DYNAMIC_LINKING != 0
if (!is_standalone_mode) {
wasm_runtime_set_module_reader(module_reader_callback, module_destroyer_impl);
wasm_program_t program = wasm_runtime_create_program(wasm_module,
stack_size, heap_size, dlopen_mode, error_buf, sizeof(error_buf));
if (!program) {
printf("%s\n", error_buf);
return 0;
}
if (is_repl_mode)
app_instance_program_repl(program, NULL);
else if (func_name)
app_instance_program_func(program, NULL, func_name);
else
app_instance_program_main(program, NULL);
printf("%s\n", error_buf);
wasm_runtime_destroy_program(program);
/* free the file buffer */
if (!is_xip_mode)
wasm_runtime_free(wasm_file_buf);
else
os_munmap(wasm_file_buf, wasm_file_size);
wasm_runtime_destroy();
return 0;
}
#endif
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 0,
@ -446,7 +652,7 @@ main(int argc, char *argv[])
fail3:
/* unload the module */
wasm_runtime_unload(wasm_module);
wasm_runtime_unload2(wasm_module);
fail2:
/* free the file buffer */

View File

@ -49,6 +49,7 @@ def ignore_the_case(
aot_flag=False,
sgx_flag=False,
multi_module_flag=False,
dlopen_flag=False,
multi_thread_flag=False,
simd_flag=False,
):
@ -98,6 +99,7 @@ def test_case(
aot_flag=False,
sgx_flag=False,
multi_module_flag=False,
dlopen_flag=False,
multi_thread_flag=False,
simd_flag=False,
clean_up_flag=True,
@ -112,6 +114,7 @@ def test_case(
aot_flag,
sgx_flag,
multi_module_flag,
dlopen_flag,
multi_thread_flag,
simd_flag,
):
@ -133,6 +136,9 @@ def test_case(
if multi_thread_flag:
CMD.append("--multi-thread")
if dlopen_flag:
CMD.append("--dlopen")
if sgx_flag:
CMD.append("--sgx")
@ -193,6 +199,7 @@ def test_suite(
aot_flag=False,
sgx_flag=False,
multi_module_flag=False,
dlopen_flag=False,
multi_thread_flag=False,
simd_flag=False,
clean_up_flag=True,
@ -215,6 +222,7 @@ def test_suite(
aot_flag,
sgx_flag,
multi_module_flag,
dlopen_flag,
multi_thread_flag,
simd_flag,
clean_up_flag,
@ -237,6 +245,7 @@ def test_suite_parallelly(
aot_flag=False,
sgx_flag=False,
multi_module_flag=False,
dlopen_flag=False,
multi_thread_flag=False,
simd_flag=False,
clean_up_flag=False,
@ -264,6 +273,7 @@ def test_suite_parallelly(
aot_flag,
sgx_flag,
multi_module_flag,
dlopen_flag,
multi_thread_flag,
simd_flag,
clean_up_flag,
@ -300,6 +310,13 @@ def main():
dest="multi_module_flag",
help="Running with the Multi-Module feature",
)
parser.add_argument(
"-D",
action="store_true",
default=False,
dest="dlopen_flag",
help="Running with dlopen feature",
)
parser.add_argument(
"-m",
action=TargetAction,
@ -385,6 +402,7 @@ def main():
options.aot_flag,
options.sgx_flag,
options.multi_module_flag,
options.dlopen_flag,
options.multi_thread_flag,
options.simd_flag,
options.clean_up_flag,
@ -401,6 +419,7 @@ def main():
options.aot_flag,
options.sgx_flag,
options.multi_module_flag,
options.dlopen_flag,
options.multi_thread_flag,
options.simd_flag,
options.clean_up_flag,
@ -417,6 +436,7 @@ def main():
options.aot_flag,
options.sgx_flag,
options.multi_module_flag,
options.dlopen_flag,
options.multi_thread_flag,
options.simd_flag,
options.clean_up_flag,

View File

@ -53,8 +53,8 @@ function run_case_w_aot() {
--aot --aot-target ${TARGET} \
${SGX_OPT} \
${SIMD_OPT} \
${REF_TYPES_OPT}
#--no_cleanup
${REF_TYPES_OPT} \
--no_cleanup
if [[ $? != 0 ]]; then
echo "============> run ${test_case} failed"
exit 1
@ -71,8 +71,8 @@ function run_case_wo_aot() {
--aot-compiler ${WAMRC_CMD} \
${SGX_OPT} \
${SIMD_OPT} \
${REF_TYPES_OPT}
#--no_cleanup
${REF_TYPES_OPT} \
--no_cleanup
if [[ $? != 0 ]]; then
echo "============> run ${test_case} failed"
exit 1

View File

@ -213,6 +213,9 @@ parser.add_argument('--simd', default=False, action='store_true',
parser.add_argument('--multi-thread', default=False, action='store_true',
help="Enable Multi-thread")
parser.add_argument('--dlopen', default=False, action='store_true',
help="Enable dlopen")
parser.add_argument('--verbose', default=False, action='store_true',
help='show more logs')
@ -965,13 +968,25 @@ def run_wasm_with_repl(wasm_tempfile, aot_tempfile, opts, r):
if not test_aot:
log("Starting interpreter for module '%s'" % wasm_tempfile)
if opts.verbose:
if opts.dlopen:
cmd = [opts.interpreter, "--heap-size=0", "-v=5", "--enable-dlopen=0", "--repl", wasm_tempfile]
else:
cmd = [opts.interpreter, "--heap-size=0", "-v=5", "--repl", wasm_tempfile]
else:
if opts.dlopen:
cmd = [opts.interpreter, "--heap-size=0", "--enable-dlopen=0", "--repl", wasm_tempfile]
else:
cmd = [opts.interpreter, "--heap-size=0", "--repl", wasm_tempfile]
else:
log("Starting aot for module '%s'" % aot_tempfile)
if opts.verbose:
if opts.dlopen:
cmd = [opts.interpreter, "--heap-size=0", "--enable-dlopen=0", "-v=5", "--repl", aot_tempfile]
else:
cmd = [opts.interpreter, "--heap-size=0", "-v=5", "--repl", aot_tempfile]
else:
if opts.dlopen:
cmd = [opts.interpreter, "--heap-size=0", "--enable-dlopen=0", "--repl", aot_tempfile]
else:
cmd = [opts.interpreter, "--heap-size=0", "--repl", aot_tempfile]

View File

@ -20,6 +20,7 @@ function help()
echo "-M enable the multi module feature"
echo "-p enable multi thread feature"
echo "-S enable SIMD"
echo "-d enable dynamic linking"
echo "-x test SGX"
echo "-b use the wabt binary release package instead of compiling from the source code"
echo "-P run the spec test parallelly"
@ -32,6 +33,8 @@ TYPE=("classic-interp" "fast-interp" "jit" "aot")
#default target
TARGET="X86_64"
ENABLE_MULTI_MODULE=0
ENABLE_DYNAMIC_LINKING=0
ENABLE_DLOPEN=0
ENABLE_MULTI_THREAD=0
COLLECT_CODE_COVERAGE=0
ENABLE_SIMD=0
@ -41,7 +44,7 @@ SGX_OPT=""
PLATFORM=$(uname -s | tr A-Z a-z)
PARALLELISM=0
while getopts ":s:cabt:m:MCpSxP" opt
while getopts ":s:cabt:m:MdDCpSxP" opt
do
OPT_PARSED="TRUE"
case $opt in
@ -94,6 +97,15 @@ do
echo "enable multi module feature"
ENABLE_MULTI_MODULE=1
;;
d)
echo "enable dynamic linking feature"
ENABLE_DYNAMIC_LINKING=1
;;
D)
echo "enable dlopen feature"
ENABLE_DYNAMIC_LINKING=1
ENABLE_DLOPEN=1
;;
C)
echo "enable code coverage"
COLLECT_CODE_COVERAGE=1
@ -156,6 +168,7 @@ readonly CLASSIC_INTERP_COMPILE_FLAGS="\
-DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=0 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \
-DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
readonly FAST_INTERP_COMPILE_FLAGS="\
@ -163,6 +176,7 @@ readonly FAST_INTERP_COMPILE_FLAGS="\
-DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=1 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \
-DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
# jit: report linking error if set COLLECT_CODE_COVERAGE,
@ -178,6 +192,7 @@ readonly AOT_COMPILE_FLAGS="\
-DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_FAST_INTERP=0 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=1 \
-DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
readonly COMPILE_FLAGS=(
@ -265,16 +280,16 @@ function spec_test()
pushd spec
# restore and clean everything
git reset --hard HEAD
#git reset --hard HEAD
# update basic test cases
echo "update spec test cases"
git fetch origin master
#git fetch origin master
# restore from XX_ignore_cases.patch
# resotre branch
git checkout -B master
git reset --hard 397399a70565609bf142d211891724e21bffd01f
git apply ../../spec-test-script/ignore_cases.patch
#git checkout -B master
#git reset --hard 397399a70565609bf142d211891724e21bffd01f
#git apply ../../spec-test-script/ignore_cases.patch
# udpate thread cases
if [ ${ENABLE_MULTI_THREAD} == 1 ]; then
@ -354,7 +369,7 @@ function spec_test()
ln -sf ${WORK_DIR}/../spec-test-script/all.py .
ln -sf ${WORK_DIR}/../spec-test-script/runtest.py .
local ARGS_FOR_SPEC_TEST=""
local ARGS_FOR_SPEC_TEST="--no_clean_up "
# multi-module only enable in interp mode
if [[ 1 == ${ENABLE_MULTI_MODULE} ]]; then
@ -386,6 +401,10 @@ function spec_test()
ARGS_FOR_SPEC_TEST+="-t -m ${TARGET} "
fi
if [[ 1 == ${ENABLE_DLOPEN} ]]; then
ARGS_FOR_SPEC_TEST+="-D "
fi
if [[ ${PARALLELISM} == 1 ]]; then
ARGS_FOR_SPEC_TEST+="--parl "
fi
@ -474,7 +493,7 @@ function build_iwasm_with_cfg()
&& if [ -d build ]; then rm -rf build/*; else mkdir build; fi \
&& cd build \
&& cmake $* .. \
&& make -j 4
&& make -j 12
fi
if [ "$?" != 0 ];then
@ -497,8 +516,8 @@ function build_wamrc()
&& ./build_llvm.sh \
&& if [ -d build ]; then rm -r build/*; else mkdir build; fi \
&& cd build \
&& cmake .. \
&& make -j 4
&& cmake .. -DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING}\
&& make -j 12
}
### Need to add a test suite?

View File

@ -36,6 +36,14 @@ add_definitions(-DWASM_ENABLE_CUSTOM_NAME_SECTION=1)
add_definitions(-DWASM_ENABLE_DUMP_CALL_STACK=1)
add_definitions(-DWASM_ENABLE_PERF_PROFILING=1)
if (WAMR_BUILD_DYNAMIC_LINKING EQUAL 1)
add_definitions (-DWASM_ENABLE_DYNAMIC_LINKING=1)
message (" Dynamic linking enabled")
else ()
add_definitions (-DWASM_ENABLE_DYNAMIC_LINKING=0)
message (" Dynamic linking disabled")
endif ()
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
if (NOT WAMR_BUILD_TARGET)
@ -66,20 +74,24 @@ elseif (WAMR_BUILD_TARGET STREQUAL "AMD_64")
add_definitions(-DBUILD_TARGET_AMD_64)
elseif (WAMR_BUILD_TARGET STREQUAL "X86_32")
add_definitions(-DBUILD_TARGET_X86_32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
add_definitions(-DBUILD_TARGET_AARCH64)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
add_definitions(-DBUILD_TARGET_ARM)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
add_definitions(-DBUILD_TARGET_RISCV64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
add_definitions(-DTARGET_32)
else ()
message (FATAL_ERROR "-- Build target isn't set")
endif ()
@ -98,6 +110,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions (-m32)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
add_definitions(-DTARGET_32)
endif ()
endif ()

View File

@ -220,6 +220,7 @@ main(int argc, char *argv[])
init_args.mem_alloc_option.allocator.malloc_func = malloc;
init_args.mem_alloc_option.allocator.realloc_func = realloc;
init_args.mem_alloc_option.allocator.free_func = free;
init_args.standalone = true;
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
@ -237,29 +238,35 @@ main(int argc, char *argv[])
goto fail1;
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file, wasm_file_size, error_buf,
sizeof(error_buf)))) {
if (!(wasm_module = wasm_runtime_load2(wasm_file_name, wasm_file, wasm_file_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail2;
}
if (!(comp_data = aot_create_comp_data(wasm_module))) {
bh_print_time("Begin to create compile context");
if (!(comp_ctx = aot_create_comp_context(&option))) {
printf("%s\n", aot_get_last_error());
goto fail3;
}
if (!(comp_data = aot_create_comp_data(wasm_module, aot_comp_ctx_get_pointer_size(comp_ctx)))) {
printf("%s\n", aot_get_last_error());
goto fail4;
}
if (!aot_bind_comp_context_data(comp_ctx, comp_data)) {
printf("%s\n", aot_get_last_error());
goto fail4;
}
#if WASM_ENABLE_DEBUG_AOT != 0
if (!create_dwarf_extractor(comp_data, wasm_file_name)) {
printf("%s:create dwarf extractor failed\n", wasm_file_name);
}
#endif
bh_print_time("Begin to create compile context");
if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
printf("%s\n", aot_get_last_error());
goto fail4;
}
bh_print_time("Begin to compile");
@ -311,7 +318,7 @@ fail3:
fail2:
/* free the file buffer */
wasm_runtime_free(wasm_file);
// wasm_runtime_free(wasm_file);
fail1:
/* Destroy runtime environment */