[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 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) [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) add_definitions(-DBUILD_TARGET_AMD_64)
elseif (WAMR_BUILD_TARGET STREQUAL "X86_32") elseif (WAMR_BUILD_TARGET STREQUAL "X86_32")
add_definitions(-DBUILD_TARGET_X86_32) add_definitions(-DBUILD_TARGET_X86_32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*") elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
if (WAMR_BUILD_TARGET MATCHES "(ARM.*)_VFP") if (WAMR_BUILD_TARGET MATCHES "(ARM.*)_VFP")
add_definitions(-DBUILD_TARGET_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_ARM)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}") add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
endif () endif ()
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*") elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
if (WAMR_BUILD_TARGET MATCHES "(THUMB.*)_VFP") if (WAMR_BUILD_TARGET MATCHES "(THUMB.*)_VFP")
add_definitions(-DBUILD_TARGET_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_THUMB)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}") add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
endif () endif ()
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
add_definitions(-DBUILD_TARGET_AARCH64) add_definitions(-DBUILD_TARGET_AARCH64)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}") add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
elseif (WAMR_BUILD_TARGET STREQUAL "MIPS") elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
add_definitions(-DBUILD_TARGET_MIPS) add_definitions(-DBUILD_TARGET_MIPS)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA") elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
add_definitions(-DBUILD_TARGET_XTENSA) add_definitions(-DBUILD_TARGET_XTENSA)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
add_definitions(-DBUILD_TARGET_RISCV64_LP64D) add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
add_definitions(-DBUILD_TARGET_RISCV64_LP64) add_definitions(-DBUILD_TARGET_RISCV64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D) add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32) add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "ARC") elseif (WAMR_BUILD_TARGET STREQUAL "ARC")
add_definitions(-DBUILD_TARGET_ARC) add_definitions(-DBUILD_TARGET_ARC)
add_definitions(-DTARGET_32)
else () else ()
message (FATAL_ERROR "-- WAMR build target isn't set") message (FATAL_ERROR "-- WAMR build target isn't set")
endif () endif ()
@ -64,6 +72,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions (-m32) add_definitions (-m32)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
add_definitions(-DTARGET_32)
endif () endif ()
endif () endif ()
@ -111,6 +120,7 @@ else ()
endif () endif ()
message ("-- Build Configurations:") message ("-- Build Configurations:")
message(" hello configcommon ")
message (" Build as target ${WAMR_BUILD_TARGET}") message (" Build as target ${WAMR_BUILD_TARGET}")
message (" CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE}) message (" CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
if (WAMR_BUILD_INTERP EQUAL 1) if (WAMR_BUILD_INTERP EQUAL 1)
@ -138,6 +148,13 @@ if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1)
else () else ()
message (" Libc builtin disabled") message (" Libc builtin disabled")
endif () 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) if (WAMR_BUILD_LIBC_UVWASI EQUAL 1)
message (" Libc WASI enabled with uvwasi implementation") message (" Libc WASI enabled with uvwasi implementation")
elseif (WAMR_BUILD_LIBC_WASI EQUAL 1) elseif (WAMR_BUILD_LIBC_WASI EQUAL 1)
@ -159,6 +176,13 @@ else ()
add_definitions (-DWASM_ENABLE_MULTI_MODULE=0) add_definitions (-DWASM_ENABLE_MULTI_MODULE=0)
message (" Multiple modules disabled") message (" Multiple modules disabled")
endif () 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) if (WAMR_BUILD_SPEC_TEST EQUAL 1)
add_definitions (-DWASM_ENABLE_SPEC_TEST=1) add_definitions (-DWASM_ENABLE_SPEC_TEST=1)
message (" spec test compatible mode is on") message (" spec test compatible mode is on")

View File

@ -161,6 +161,18 @@ GET_U64_FROM_ADDR(uint32 *addr)
goto fail; \ goto fail; \
} while (0) } 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 */ /* Legal values for bin_type */
#define BIN_TYPE_ELF32L 0 /* 32-bit little endian */ #define BIN_TYPE_ELF32L 0 /* 32-bit little endian */
#define BIN_TYPE_ELF32B 1 /* 32-bit big 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; HashMap *set = module->const_str_set;
char *c_str, *value; char *c_str, *value;
ConstStrDescription temp_key;
ConstStrDescription * key = NULL;
uint32 req_size = 0;
/* Create const string set if it isn't created */ temp_key.str = (void*)str;
if (!set temp_key.len = len;
&& !(set = module->const_str_set = bh_hash_map_create( temp_key.hash = 0;
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;
}
/* Lookup const string set, use the string if found */ if ((value = bh_hash_map_find(set, &temp_key))) {
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);
return value; 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, set_error_buf(error_buf, error_buf_size,
"insert string to hash map failed"); "insert string to hash map failed");
wasm_runtime_free(c_str); wasm_runtime_free(key);
return NULL; 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, AOTModule *module, bool is_load_from_file_buf,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
WASMRuntime * runtime = module->runtime;
const uint8 *buf = *p_buf; const uint8 *buf = *p_buf;
AOTImportGlobal *import_globals; AOTImportGlobal *import_globals;
uint64 size; uint64 size = 0;
uint32 i, data_offset = 0; uint32 i, data_offset = 0;
#if WASM_ENABLE_LIBC_BUILTIN != 0 #if WASM_ENABLE_LIBC_BUILTIN != 0
WASMGlobalImport tmp_global; WASMGlobalImport tmp_global;
@ -1068,25 +1086,50 @@ load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
buf = (uint8 *)align_ptr(buf, 2); buf = (uint8 *)align_ptr(buf, 2);
read_uint8(buf, buf_end, import_globals[i].type); read_uint8(buf, buf_end, import_globals[i].type);
read_uint8(buf, buf_end, import_globals[i].is_mutable); read_uint8(buf, buf_end, import_globals[i].is_mutable);
read_string(buf, buf_end, import_globals[i].module_name); //read_uint16(buf, buf_end, name_len);
read_string(buf, buf_end, import_globals[i].global_name); //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_ENABLE_LIBC_BUILTIN != 0
if (wasm_native_lookup_libc_builtin_global( if (wasm_native_lookup_libc_builtin_global(
import_globals[i].module_name, import_globals[i].global_name, import_globals[i].module_name->str,
&tmp_global)) { import_globals[i].global_name->str,
&tmp_global)) {
if (tmp_global.type != import_globals[i].type if (tmp_global.type != import_globals[i].type
|| tmp_global.is_mutable != import_globals[i].is_mutable) { || tmp_global.is_mutable != import_globals[i].is_mutable) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"incompatible import type"); "incompatible import type");
return false; return false;
} }
bh_assert(import_globals[i].is_mutable == false);
import_globals[i].global_data_linked = import_globals[i].global_data_linked =
tmp_global.global_data_linked; tmp_global.global_data_linked;
} }
#endif #endif
import_globals[i].size = wasm_value_type_size(import_globals[i].type); 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; import_globals[i].data_offset = data_offset;
data_offset += import_globals[i].size; data_offset += import_globals[i].size;
module->global_data_size += 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, bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size) uint32 error_buf_size)
{ {
const char *module_name, *field_name; WASMRuntime * runtime = module->runtime;
const uint8 *buf = *p_buf; const uint8 *buf = *p_buf;
AOTImportFunc *import_funcs; AOTImportFunc *import_funcs;
uint64 size; 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"); set_error_buf(error_buf, error_buf_size, "unknown type");
return false; return false;
} }
import_funcs[i].func_type = import_funcs[i].func_type = module->func_types[import_funcs[i].func_type_index];
module->func_types[import_funcs[i].func_type_index]; csp_read_string(buf, buf_end, import_funcs[i].module_name);
read_string(buf, buf_end, import_funcs[i].module_name); csp_read_string(buf, buf_end, import_funcs[i].func_name);
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( 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].signature, &import_funcs[i].attachment,
&import_funcs[i].call_conv_raw); &import_funcs[i].call_conv_raw);
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
if (!strcmp(import_funcs[i].module_name, "wasi_unstable") if (import_funcs[i].module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_unstable)
|| !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1")) || import_funcs[i].module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_snapshot_preview1))
module->is_wasi_module = true; module->is_wasi_module = true;
#endif #endif
} }
@ -1372,6 +1412,83 @@ fail:
return false; 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 static bool
load_init_data_section(const uint8 *buf, const uint8 *buf_end, load_init_data_section(const uint8 *buf, const uint8 *buf_end,
AOTModule *module, bool is_load_from_file_buf, 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; AOTExport *exports;
uint64 size; uint64 size;
uint32 i; uint32 i;
#if WASM_ENABLE_DYNAMIC_LINKING != 0
WASMRuntime * runtime = module->runtime;
#endif
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTExport) * (uint64)module->export_count; 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_uint32(buf, buf_end, exports[i].index);
read_uint8(buf, buf_end, exports[i].kind); read_uint8(buf, buf_end, exports[i].kind);
read_string(buf, buf_end, exports[i].name); 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 0 /* TODO: check kind and index */
if (export_funcs[i].index >= if (export_funcs[i].index >=
module->func_count + module->import_func_count) { 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; *p_buf = buf;
return true; return true;
fail: fail:
return false; return false;
@ -2280,6 +2422,11 @@ load_from_sections(AOTModule *module, AOTSection *sections,
error_buf_size)) error_buf_size))
return false; return false;
break; 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: case AOT_SECTION_TYPE_INIT_DATA:
if (!load_init_data_section(buf, buf_end, module, if (!load_init_data_section(buf, buf_end, module,
is_load_from_file_buf, error_buf, 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[0] == VALUE_TYPE_I32
&& func_type->types[1] == VALUE_TYPE_I32) { && func_type->types[1] == VALUE_TYPE_I32) {
bh_assert(module->malloc_func_index == (uint32)-1); 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", LOG_VERBOSE("Found malloc function, name: %s, index: %u",
exports[i].name, exports[i].index); exports[i].name, exports[i].index);
} }
@ -2363,7 +2510,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
WASMExport *export_tmp; WASMExport *export_tmp;
bh_assert(module->malloc_func_index == (uint32)-1); 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", LOG_VERBOSE("Found malloc function, name: %s, index: %u",
exports[i].name, exports[i].index); 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 if (func_type->param_count == 1 && func_type->result_count == 0
&& func_type->types[0] == VALUE_TYPE_I32) { && func_type->types[0] == VALUE_TYPE_I32) {
bh_assert(module->free_func_index == (uint32)-1); 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", LOG_VERBOSE("Found free function, name: %s, index: %u",
exports[i].name, exports[i].index); 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; 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; 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 static bool
resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count, resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count,
char *error_buf, uint32 error_buf_size) 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_type;
uint32 section_size = 0; uint32 section_size = 0;
p += 8; p += AOT_HEADER_SIZE;
while (p < p_end) { while (p < p_end) {
read_uint32(p, p_end, section_type); read_uint32(p, p_end, section_type);
if (section_type <= AOT_SECTION_TYPE_SIGANATURE 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; module->native_symbol_count = native_symbol_count;
p += 8; p += AOT_HEADER_SIZE;
while (p < p_end) { while (p < p_end) {
read_uint32(p, p_end, section_type); read_uint32(p, p_end, section_type);
if (section_type < AOT_SECTION_TYPE_SIGANATURE 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 *buf_end = buf + size;
const uint8 *p = buf, *p_end = buf_end; 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; AOTSection *section_list = NULL;
bool ret; bool ret;
@ -2656,8 +2826,24 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
return false; return false;
} }
if (!create_sections(module, buf, size, &section_list, error_buf, read_uint64(p, p_end, aot_features);
error_buf_size)) #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; return false;
ret = load_from_sections(module, section_list, true, error_buf, 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: fail:
return false; return false;
} }
#undef AOT_HEADER_SIZE
AOTModule * AOTModule *
aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf, 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; goto fail3;
} }
for (i = 0; i < comp_data->func_count; i++) 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->export_count = comp_data->wasm_module->export_count;
module->exports = comp_data->wasm_module->exports; 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; module->start_func_index = comp_data->start_func_index;
if (comp_data->start_func_index != (uint32)-1) { if (comp_data->start_func_index != (uint32)-1) {
bh_assert(comp_data->start_func_index bh_assert(comp_data->start_func_index
@ -2909,14 +3101,6 @@ aot_convert_wasm_module(WASMModule *wasm_module, char *error_buf,
AOTCompOption option = { 0 }; AOTCompOption option = { 0 };
char *aot_last_error; 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; option.is_jit_mode = true;
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
option.enable_bulk_memory = true; 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; option.enable_aux_stack_frame = true;
#endif #endif
comp_ctx = aot_create_comp_context(comp_data, &option); comp_ctx = aot_create_comp_context(&option);
if (!comp_ctx) { 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(); aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL); bh_assert(aot_last_error != NULL);
set_error_buf(error_buf, error_buf_size, aot_last_error); set_error_buf(error_buf, error_buf_size, aot_last_error);
goto fail1; 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)) { if (!aot_compile_wasm(comp_ctx)) {
aot_last_error = aot_get_last_error(); aot_last_error = aot_get_last_error();
bh_assert(aot_last_error != NULL); bh_assert(aot_last_error != NULL);
@ -2962,9 +3161,9 @@ aot_convert_wasm_module(WASMModule *wasm_module, char *error_buf,
return aot_module; return aot_module;
fail2: fail2:
aot_destroy_comp_context(comp_ctx);
fail1:
aot_destroy_comp_data(comp_data); aot_destroy_comp_data(comp_data);
fail1:
aot_destroy_comp_context(comp_ctx);
return NULL; return NULL;
} }
#endif #endif
@ -3071,6 +3270,12 @@ aot_unload(AOTModule *module)
} }
#endif #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); wasm_runtime_free(module);
} }

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@ typedef enum AOTExceptionID {
EXCE_UNDEFINED_ELEMENT, EXCE_UNDEFINED_ELEMENT,
EXCE_UNINITIALIZED_ELEMENT, EXCE_UNINITIALIZED_ELEMENT,
EXCE_CALL_UNLINKED_IMPORT_FUNC, EXCE_CALL_UNLINKED_IMPORT_FUNC,
EXEC_CALL_UNLINKED_MODULE,
EXCE_NATIVE_STACK_OVERFLOW, EXCE_NATIVE_STACK_OVERFLOW,
EXCE_UNALIGNED_ATOMIC, EXCE_UNALIGNED_ATOMIC,
EXCE_AUX_STACK_OVERFLOW, EXCE_AUX_STACK_OVERFLOW,
@ -40,12 +41,13 @@ typedef enum AOTExceptionID {
typedef enum AOTSectionType { typedef enum AOTSectionType {
AOT_SECTION_TYPE_TARGET_INFO = 0, AOT_SECTION_TYPE_TARGET_INFO = 0,
AOT_SECTION_TYPE_INIT_DATA = 1, AOT_SECTION_TYPE_DYLINK = 1,
AOT_SECTION_TYPE_TEXT = 2, AOT_SECTION_TYPE_INIT_DATA = 2,
AOT_SECTION_TYPE_FUNCTION = 3, AOT_SECTION_TYPE_TEXT = 3 ,
AOT_SECTION_TYPE_EXPORT = 4, AOT_SECTION_TYPE_FUNCTION = 4,
AOT_SECTION_TYPE_RELOCATION = 5, AOT_SECTION_TYPE_EXPORT = 5,
AOT_SECTION_TYPE_SIGANATURE = 6, AOT_SECTION_TYPE_RELOCATION = 6,
AOT_SECTION_TYPE_SIGANATURE = 7,
AOT_SECTION_TYPE_CUSTOM = 100, AOT_SECTION_TYPE_CUSTOM = 100,
} AOTSectionType; } AOTSectionType;
@ -81,8 +83,8 @@ typedef struct AOTRelocationGroup {
} AOTRelocationGroup; } AOTRelocationGroup;
/* AOT function instance */ /* AOT function instance */
typedef struct AOTFunctionInstance { typedef struct AOTExportFunctionInstance {
char *func_name; const char *func_name;
uint32 func_index; uint32 func_index;
bool is_import_func; bool is_import_func;
union { union {
@ -93,7 +95,7 @@ typedef struct AOTFunctionInstance {
} func; } func;
AOTImportFunc *func_import; AOTImportFunc *func_import;
} u; } u;
} AOTFunctionInstance; } AOTExportFunctionInstance;
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS) #if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
/* clang-format off */ /* clang-format off */
@ -122,6 +124,8 @@ typedef struct AOTUnwindInfo {
typedef struct AOTModule { typedef struct AOTModule {
uint32 module_type; uint32 module_type;
WASMDylinkSection * dylink_section;
/* import memories */ /* import memories */
uint32 import_memory_count; uint32 import_memory_count;
AOTImportMemory *import_memories; AOTImportMemory *import_memories;
@ -178,6 +182,10 @@ typedef struct AOTModule {
/* export info */ /* export info */
uint32 export_count; uint32 export_count;
uint32 export_func_count;
uint32 export_global_count;
uint32 export_mem_count;
uint32 export_tab_count;
AOTExport *exports; AOTExport *exports;
/* start function index, -1 denotes no start function */ /* start function index, -1 denotes no start function */
@ -246,6 +254,16 @@ typedef struct AOTModule {
/* is jit mode or not */ /* is jit mode or not */
bool is_jit_mode; 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 #if WASM_ENABLE_JIT != 0
WASMModule *wasm_module; WASMModule *wasm_module;
AOTCompContext *comp_ctx; AOTCompContext *comp_ctx;
@ -321,7 +339,28 @@ typedef struct AOTTableInstance {
typedef struct AOTModuleInstance { typedef struct AOTModuleInstance {
uint32 module_type; 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 */ /* memories */
uint32 memory_count; uint32 memory_count;
AOTPointer memories; AOTPointer memories;
@ -339,6 +378,8 @@ typedef struct AOTModuleInstance {
AOTPointer global_data; AOTPointer global_data;
/* points to AOTTableInstance[] */ /* points to AOTTableInstance[] */
AOTPointer tables; AOTPointer tables;
AOTPointer global_table_data_end;
/* function pointer array */ /* function pointer array */
AOTPointer func_ptrs; AOTPointer func_ptrs;
@ -346,15 +387,19 @@ typedef struct AOTModuleInstance {
AOTPointer func_type_indexes; AOTPointer func_type_indexes;
/* export info */ /* export info */
uint32 export_func_count; //uint32 export_func_count;
uint32 export_global_count; //uint32 export_global_count;
uint32 export_mem_count; //uint32 export_mem_count;
uint32 export_tab_count; //uint32 export_tab_count;
AOTPointer export_funcs; AOTPointer export_funcs;
AOTPointer export_globals; AOTPointer export_globals;
AOTPointer export_memories; AOTPointer export_memories;
AOTPointer export_tables; AOTPointer export_tables;
AOTPointer malloc_func;
AOTPointer retain_func;
AOTPointer free_func;
/* The exception buffer for current thread. */ /* The exception buffer for current thread. */
char cur_exception[128]; char cur_exception[128];
/* The custom data that can be set/get by /* The custom data that can be set/get by
@ -496,10 +541,15 @@ aot_unload(AOTModule *module);
* *
* @return return the instantiated AOT module instance, NULL if failed * @return return the instantiated AOT module instance, NULL if failed
*/ */
AOTModuleInstance * AOTModuleInstance*
aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size, aot_instantiate(WASMProgramInstance * program, AOTModule *module, bool is_sub_inst,
uint32 heap_size, char *error_buf, uint32 error_buf_size); 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. * 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 * @return the function instance found
*/ */
AOTFunctionInstance * AOTExportFunctionInstance *
aot_lookup_function(const AOTModuleInstance *module_inst, const char *name, aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
const char *signature); 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. * the caller can call aot_get_exception to get exception info.
*/ */
bool bool
aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, aot_call_function(WASMExecEnv *exec_env, AOTExportFunctionInstance *function,
unsigned argc, uint32 argv[]); unsigned argc, uint32 argv[]);
bool bool
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst, aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
AOTFunctionInstance *function, AOTExportFunctionInstance *function,
unsigned argc, uint32 argv[]); unsigned argc, uint32 argv[]);
bool bool
@ -645,6 +695,15 @@ bool
aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx, aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
uint32 argc, uint32 *argv); 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 uint32
aot_get_plt_table_size(); aot_get_plt_table_size();
@ -725,6 +784,20 @@ aot_dump_call_stack(WASMExecEnv *exec_env);
void void
aot_dump_perf_profiling(const AOTModuleInstance *module_inst); 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 #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #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 #endif
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) { 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 #endif
@ -188,6 +188,19 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
return ret; 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 #if WASM_ENABLE_MULTI_MODULE != 0
static WASMModuleInstance * static WASMModuleInstance *
get_sub_module_inst(const WASMModuleInstance *parent_module_inst, get_sub_module_inst(const WASMModuleInstance *parent_module_inst,
@ -294,10 +307,11 @@ resolve_function(const WASMModuleInstanceCommon *module_inst, const char *name)
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) { if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst; AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
AOTFunctionInstance *export_funcs = AOTModule * aot_module = (AOTModule *)aot_inst->aot_module.ptr;
(AOTFunctionInstance *)aot_inst->export_funcs.ptr; AOTExportFunctionInstance *export_funcs = (AOTExportFunctionInstance *)
for (i = 0; i < aot_inst->export_func_count; i++) { aot_inst->export_funcs.ptr;
for (i = 0; i < aot_module->export_func_count; i++) {
if (!strcmp(export_funcs[i].func_name, function_name)) { if (!strcmp(export_funcs[i].func_name, function_name)) {
ret = &export_funcs[i]; ret = &export_funcs[i];
break; break;
@ -681,3 +695,15 @@ fail:
os_printf("%s\n", exception); os_printf("%s\n", exception);
return false; 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) { 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) { if (i < import_func_count) {
wasm_functype_t *type = NULL; 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) { if ((*module)->module_type == Wasm_Module_Bytecode) {
WASMImport *import = WASMImport *import =
MODULE_INTERP(module)->import_functions + i; MODULE_INTERP(module)->import_functions + i;
module_name_rt = import->u.names.module_name; module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = import->u.names.field_name; field_name_rt = (char*)import->u.names.field_name->str;
type_rt = import->u.function.func_type; type_rt = import->u.function.func_type;
} }
#endif #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 WASM_ENABLE_AOT != 0
if ((*module)->module_type == Wasm_Module_AoT) { if ((*module)->module_type == Wasm_Module_AoT) {
AOTImportFunc *import = MODULE_AOT(module)->import_funcs + i; AOTImportFunc *import = MODULE_AOT(module)->import_funcs + i;
module_name_rt = import->module_name; module_name_rt = import->module_name->str;
field_name_rt = import->func_name; field_name_rt = import->func_name->str;
type_rt = import->func_type; type_rt = import->func_type;
} }
#endif #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) { if ((*module)->module_type == Wasm_Module_Bytecode) {
WASMImport *import = MODULE_INTERP(module)->import_globals WASMImport *import = MODULE_INTERP(module)->import_globals
+ (i - import_func_count); + (i - import_func_count);
module_name_rt = import->u.names.module_name; module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = import->u.names.field_name; field_name_rt = (char*)import->u.names.field_name->str;
val_type_rt = import->u.global.type; val_type_rt = import->u.global.type;
mutability_rt = import->u.global.is_mutable; 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 WASM_ENABLE_AOT != 0
if ((*module)->module_type == Wasm_Module_AoT) { if ((*module)->module_type == Wasm_Module_AoT) {
AOTImportGlobal *import = MODULE_AOT(module)->import_globals AOTImportGlobal *import =
+ (i - import_func_count); MODULE_AOT(module)->import_globals + (i - import_func_count);
module_name_rt = import->module_name; module_name_rt = import->module_name->str;
field_name_rt = import->global_name; field_name_rt = import->global_name->str;
val_type_rt = import->type; val_type_rt = import->type;
mutability_rt = import->is_mutable; 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 = WASMImport *import =
MODULE_INTERP(module)->import_memories MODULE_INTERP(module)->import_memories
+ (i - import_func_count - import_global_count); + (i - import_func_count - import_global_count);
module_name_rt = import->u.names.module_name; module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = import->u.names.field_name; field_name_rt = (char*)import->u.names.field_name->str;
min_page = import->u.memory.init_page_count; min_page = import->u.memory.init_page_count;
max_page = import->u.memory.max_page_count; max_page = import->u.memory.max_page_count;
} }
@ -2143,9 +2143,9 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
WASMImport *import = WASMImport *import =
MODULE_INTERP(module)->import_tables MODULE_INTERP(module)->import_tables
+ (i - import_func_count - import_global_count + (i - import_func_count - import_global_count
- import_memory_count); - import_memory_count);
module_name_rt = import->u.names.module_name; module_name_rt = (char*)import->u.names.module_name->str;
field_name_rt = import->u.names.field_name; field_name_rt = (char*)import->u.names.field_name->str;
elem_type_rt = import->u.table.elem_type; elem_type_rt = import->u.table.elem_type;
min_size = import->u.table.init_size; min_size = import->u.table.init_size;
max_size = import->u.table.max_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->kind == EXPORT_KIND_FUNC) {
if (export->index == func->func_idx_rt) { if (export->index == func->func_idx_rt) {
func_comm_rt = func_comm_rt =
(AOTFunctionInstance *)inst_aot->export_funcs.ptr (AOTExportFunctionInstance *)inst_aot->export_funcs.ptr
+ export_func_j; + export_func_j;
((wasm_func_t *)func)->func_comm_rt = func_comm_rt; ((wasm_func_t *)func)->func_comm_rt = func_comm_rt;
break; break;
@ -2949,12 +2949,16 @@ interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt,
inst_interp->globals + global_idx_rt; inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type; uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0 #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 uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data ? global_interp->import_global_inst->data
+ global_interp->import_global_inst->data_offset : global_interp->data;
: inst_interp->global_data + global_interp->data_offset;
#else #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 #endif
return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_interp, 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; WASMGlobalInstance *global_interp = inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type; uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0 #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 uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data ? global_interp->import_global_inst->data
+ global_interp->import_global_inst->data_offset : global_interp->data;
: inst_interp->global_data + global_interp->data_offset;
#else #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 #endif
return rt_val_to_wasm_val(data, val_type_rt, out); 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 WASM_ENABLE_AOT != 0
if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) { if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) {
uint32 export_cnt = AOTModule * aot_module = (AOTModule*)((AOTModuleInstance *)instance->inst_comm_rt)->aot_module.ptr;
((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count uint32 export_cnt = aot_module->export_count;
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count // ((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_tab_count // + ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_mem_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, INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized,
export_cnt); 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 * void *
wasm_runtime_malloc(unsigned int size) wasm_runtime_malloc(unsigned int size)
{ {
bh_assert(size != 0);
if (size == 0) { if (size == 0) {
LOG_WARNING("warning: wasm_runtime_malloc with size zero\n"); LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
/* At lease alloc 1 byte to avoid malloc failed */ /* At lease alloc 1 byte to avoid malloc failed */
size = 1; size = 1;
} }
malloc_times ++;
return wasm_runtime_malloc_internal(size); return wasm_runtime_malloc_internal(size);
} }
void * void *
wasm_runtime_realloc(void *ptr, unsigned int size) wasm_runtime_realloc(void *ptr, unsigned int size)
{ {
realloc_times ++;
return wasm_runtime_realloc_internal(ptr, size); return wasm_runtime_realloc_internal(ptr, size);
} }
void void
wasm_runtime_free(void *ptr) wasm_runtime_free(void *ptr)
{ {
free_times ++;
wasm_runtime_free_internal(ptr); 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> #include <sys/time.h>
#endif #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 uint32
get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis); 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 uint32
get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis); get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
static bool bool
check_symbol_signature(const WASMType *type, const char *signature) check_symbol_signature(const WASMType *type, const char *signature)
{ {
const char *p = signature, *p_end; const char *p = signature, *p_end;
@ -121,7 +150,7 @@ check_symbol_signature(const WASMType *type, const char *signature)
return true; return true;
} }
/*
#if ENABLE_QUICKSORT == 0 #if ENABLE_QUICKSORT == 0
static void static void
sort_symbol_ptr(NativeSymbol *native_symbols, uint32 n_native_symbols) 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, pin_left, left - 1);
quick_sort_symbols(native_symbols, left + 1, pin_right); quick_sort_symbols(native_symbols, left + 1, pin_right);
} }
#endif /* end of ENABLE_QUICKSORT */ #endif
*/
static void * static void *
lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols, 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 low = 0, mid, ret;
int high = (int32)n_native_symbols - 1; int high = (int32)n_native_symbols - 1;
@ -210,19 +239,78 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
else else
low = mid + 1; 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; return NULL;
} }
void * void *
wasm_native_resolve_symbol(const char *module_name, const char *field_name, wasm_native_resolve_symbol(const ConstStrDescription *module_name,
const WASMType *func_type, const char **p_signature, const ConstStrDescription ** p_field_name,
void **p_attachment, bool *p_call_conv_raw) 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 char *signature = NULL;
const ConstStrDescription * field_name = *p_field_name;
void *func_ptr = NULL, *attachment; 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; node = g_native_symbols_list;
while (node) { while (node) {
node_next = node->next; node_next = node->next;
@ -238,18 +326,32 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
} }
node = node_next; node = node_next;
} }
#endif
if (func_ptr) { if (func_ptr) {
if (signature && signature[0] != '\0') { if (signature && signature[0] != '\0') {
/* signature is not empty, check its format */ /* signature is not empty, check its format */
if (!check_symbol_signature(func_type, signature)) { 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 #if WASM_ENABLE_WAMR_COMPILER == 0
/* Output warning except running aot compiler */ /* Output warning except running aot compiler */
LOG_WARNING("failed to check signature '%s' and resolve " LOG_WARNING("failed to check signature '%s' and resolve "
"pointer params for import function (%s %s)\n", "pointer params for import function (%s %s)\n",
signature, module_name, field_name); signature, module_name, field_name);
#endif #endif
return NULL; return NULL;
}
} }
else else
/* Save signature for runtime to do pointer check and /* Save signature for runtime to do pointer check and
@ -271,28 +373,53 @@ static bool
register_natives(const char *module_name, NativeSymbol *native_symbols, register_natives(const char *module_name, NativeSymbol *native_symbols,
uint32 n_native_symbols, bool call_conv_raw) uint32 n_native_symbols, bool call_conv_raw)
{ {
NativeSymbolsNode *node; WASMRuntime * runtime = wasm_runtime_get_runtime();
/*
#if ENABLE_SORT_DEBUG != 0 #if ENABLE_SORT_DEBUG != 0
struct timeval start; struct timeval start;
struct timeval end; struct timeval end;
unsigned long timer; unsigned long timer;
#endif #endif
*/
if (!(node = wasm_runtime_malloc(sizeof(NativeSymbolsNode)))) if (!runtime)
return false; return false;
#if WASM_ENABLE_MEMORY_TRACING != 0
os_printf("Register native, size: %u\n", sizeof(NativeSymbolsNode));
#endif
node->module_name = module_name; if ((g_native_libs_count + 1) > g_native_libs_size) {
node->native_symbols = native_symbols; g_native_symbols_vec = wasm_runtime_realloc(
node->n_native_symbols = n_native_symbols; g_native_symbols_vec, (g_native_libs_size + 2) * sizeof(NativeSymbolsNode));
node->call_conv_raw = call_conv_raw; if (!g_native_symbols_vec) {
return false;
}
/* Add to list head */ g_native_libs_size += 2;
node->next = g_native_symbols_list; bh_assert((g_native_libs_count + 2) == g_native_libs_size);
g_native_symbols_list = node; }
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 #if ENABLE_SORT_DEBUG != 0
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
#endif #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, LOG_ERROR("module_name: %s, nums: %d, sorted used: %ld us", module_name,
n_native_symbols, timer); n_native_symbols, timer);
#endif #endif
*/
return true; return true;
} }
@ -334,46 +462,94 @@ wasm_native_register_natives_raw(const char *module_name,
bool bool
wasm_native_init() wasm_native_init()
{ {
WASMRuntime * runtime = wasm_runtime_get_runtime();
NativeSymbol *native_symbols; 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 #if WASM_ENABLE_LIBC_BUILTIN != 0
n_native_symbols = get_libc_builtin_export_apis(&native_symbols); n_native_symbols = get_libc_builtin_export_apis(&native_symbols);
if (!wasm_native_register_natives("env", native_symbols, n_native_symbols)) //if (!wasm_native_register_natives(CONST_STR_POOL_DESC(WAMR_CSP_env), native_symbols, n_native_symbols))
return false; // return false;
#endif /* WASM_ENABLE_LIBC_BUILTIN */ 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); n_native_symbols = get_spectest_export_apis(&native_symbols);
if (!wasm_native_register_natives("spectest", native_symbols, if (n_native_symbols) {
n_native_symbols)) for (uint32 i = 0; i < n_native_symbols; i ++)
return false; native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
#endif /* WASM_ENABLE_SPEC_TEST */
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 #if WASM_ENABLE_LIBC_WASI != 0
n_native_symbols = get_libc_wasi_export_apis(&native_symbols); n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
if (!wasm_native_register_natives("wasi_unstable", native_symbols, if (n_native_symbols) {
n_native_symbols)) for (uint32 i = 0; i < n_native_symbols; i ++)
return false; native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
if (!wasm_native_register_natives("wasi_snapshot_preview1", native_symbols,
n_native_symbols)) g_native_symbols_vec[ID_LIBC_WASI_UNSTABLE].module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_wasi_unstable);
return false; 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 #endif
#if WASM_ENABLE_BASE_LIB != 0 #if WASM_ENABLE_BASE_LIB != 0
n_native_symbols = get_base_lib_export_apis(&native_symbols); n_native_symbols = get_base_lib_export_apis(&native_symbols);
if (n_native_symbols > 0 if (n_native_symbols) {
&& !wasm_native_register_natives("env", native_symbols, for (uint32 i = 0; i < n_native_symbols; i ++)
n_native_symbols)) native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
return false;
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 #endif
#if WASM_ENABLE_APP_FRAMEWORK != 0 #if WASM_ENABLE_APP_FRAMEWORK != 0
n_native_symbols = get_ext_lib_export_apis(&native_symbols); n_native_symbols = get_ext_lib_export_apis(&native_symbols);
if (n_native_symbols > 0 if (n_native_symbols) {
&& !wasm_native_register_natives("env", native_symbols, for (uint32 i = 0; i < n_native_symbols; i ++)
n_native_symbols)) native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
return false;
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 #endif
#if WASM_ENABLE_LIB_PTHREAD != 0 #if WASM_ENABLE_LIB_PTHREAD != 0
@ -381,19 +557,29 @@ wasm_native_init()
return false; return false;
n_native_symbols = get_lib_pthread_export_apis(&native_symbols); n_native_symbols = get_lib_pthread_export_apis(&native_symbols);
if (n_native_symbols > 0 if (n_native_symbols) {
&& !wasm_native_register_natives("env", native_symbols, for (uint32 i = 0; i < n_native_symbols; i ++)
n_native_symbols)) native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
return false;
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 #endif
#if WASM_ENABLE_LIBC_EMCC != 0 #if WASM_ENABLE_LIBC_EMCC != 0
n_native_symbols = get_libc_emcc_export_apis(&native_symbols); n_native_symbols = get_libc_emcc_export_apis(&native_symbols);
if (n_native_symbols > 0 if (n_native_symbols) {
&& !wasm_native_register_natives("env", native_symbols, for (uint32 i = 0; i < n_native_symbols; i ++)
n_native_symbols)) native_symbols[i].u.symbol = CONST_STR_POOL_DESC(runtime, native_symbols[i].u.symbol_key);
return false;
#endif /* WASM_ENABLE_LIBC_EMCC */ 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; return true;
} }
@ -401,18 +587,17 @@ wasm_native_init()
void void
wasm_native_destroy() wasm_native_destroy()
{ {
NativeSymbolsNode *node, *node_next;
#if WASM_ENABLE_LIB_PTHREAD != 0 #if WASM_ENABLE_LIB_PTHREAD != 0
lib_pthread_destroy(); lib_pthread_destroy();
#endif #endif
node = g_native_symbols_list; for (uint32 i = ID_USER; i < g_native_libs_count; i ++) {
while (node) { if (g_native_symbols_vec[i].native_symbols)
node_next = node->next; wasm_runtime_free(g_native_symbols_vec[i].native_symbols);
wasm_runtime_free(node);
node = node_next;
} }
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 #endif
typedef struct NativeSymbolsNode { typedef struct NativeSymbolsNode {
struct NativeSymbolsNode *next; //struct NativeSymbolsNode *next;
const char *module_name; const ConstStrDescription *module_name;
NativeSymbol *native_symbols; NativeSymbol *native_symbols;
uint32 n_native_symbols; uint32 n_native_symbols;
bool call_conv_raw; bool call_conv_raw;
} NativeSymbolsNode, *NativeSymbolsList; } NativeSymbolsNode, *NativeSymbolsVec;
/** /**
* Lookup global variable of a given import global * Lookup global variable of a given import global
@ -50,9 +50,10 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
* @return the native function pointer if success, NULL otherwise * @return the native function pointer if success, NULL otherwise
*/ */
void * void *
wasm_native_resolve_symbol(const char *module_name, const char *field_name, wasm_native_resolve_symbol(const ConstStrDescription *module_name,
const WASMType *func_type, const char **p_signature, const ConstStrDescription ** p_field_name,
void **p_attachment, bool *p_call_conv_raw); const WASMType *func_type, const char **p_signature,
void **p_attachment, bool *p_call_conv_raw);
bool bool
wasm_native_register_natives(const char *module_name, wasm_native_register_natives(const char *module_name,
@ -70,6 +71,9 @@ wasm_native_init();
void void
wasm_native_destroy(); wasm_native_destroy();
bool
check_symbol_signature(const WASMType *type, const char *signature);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -99,13 +99,9 @@ wasm_runtime_env_init()
if (bh_platform_init() != 0) if (bh_platform_init() != 0)
return false; return false;
if (wasm_native_init() == false) {
goto fail1;
}
#if WASM_ENABLE_MULTI_MODULE #if WASM_ENABLE_MULTI_MODULE
if (BHT_OK != os_mutex_init(&registered_module_list_lock)) { if (BHT_OK != os_mutex_init(&registered_module_list_lock)) {
goto fail2; goto fail1;
} }
if (BHT_OK != os_mutex_init(&loading_module_list_lock)) { if (BHT_OK != os_mutex_init(&loading_module_list_lock)) {
@ -171,12 +167,9 @@ fail4:
os_mutex_destroy(&loading_module_list_lock); os_mutex_destroy(&loading_module_list_lock);
fail3: fail3:
os_mutex_destroy(&registered_module_list_lock); os_mutex_destroy(&registered_module_list_lock);
fail2:
#endif
wasm_native_destroy();
fail1: fail1:
bh_platform_destroy(); bh_platform_destroy();
#endif
return false; return false;
} }
@ -200,6 +193,16 @@ wasm_runtime_init()
return false; 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; return true;
} }
@ -240,6 +243,9 @@ wasm_runtime_destroy()
#endif #endif
wasm_native_destroy(); wasm_native_destroy();
wasm_runtime_runtime_destroy();
bh_platform_destroy(); bh_platform_destroy();
wasm_runtime_memory_destroy(); wasm_runtime_memory_destroy();
@ -253,7 +259,13 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
return false; return false;
if (!wasm_runtime_env_init()) { 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; return false;
} }
@ -267,6 +279,11 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
} }
#endif #endif
if (!wasm_native_init()) {
wasm_runtime_destroy();
return false;
}
if (init_args->n_native_symbols > 0 if (init_args->n_native_symbols > 0
&& !wasm_runtime_register_natives(init_args->native_module_name, && !wasm_runtime_register_natives(init_args->native_module_name,
init_args->native_symbols, init_args->native_symbols,
@ -294,29 +311,8 @@ get_package_type(const uint8 *buf, uint32 size)
return Package_Type_Unknown; return Package_Type_Unknown;
} }
#if WASM_ENABLE_MULTI_MODULE != 0 #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 * static WASMRegisteredModule *
wasm_runtime_find_module_registered_by_reference(WASMModuleCommon *module) wasm_runtime_find_module_registered_by_reference(WASMModuleCommon *module)
{ {
@ -491,12 +487,12 @@ wasm_runtime_destroy_registered_module_list()
} }
/* destroy the file buffer */ /* destroy the file buffer */
if (destroyer && reg_module->orig_file_buf) { //if (destroyer && reg_module->orig_file_buf) {
destroyer(reg_module->orig_file_buf, // destroyer(reg_module->orig_file_buf,
reg_module->orig_file_buf_size); // reg_module->orig_file_buf_size);
reg_module->orig_file_buf = NULL; // reg_module->orig_file_buf = NULL;
reg_module->orig_file_buf_size = 0; // reg_module->orig_file_buf_size = 0;
} //}
wasm_runtime_free(reg_module); wasm_runtime_free(reg_module);
reg_module = next_reg_module; reg_module = next_reg_module;
@ -600,6 +596,18 @@ wasm_runtime_is_built_in_module(const char *module_name)
|| !strcmp("", 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 #if WASM_ENABLE_THREAD_MGR != 0
bool bool
wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, 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 #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 * WASMModuleCommon *
wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf, wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
uint32 error_buf_size) uint32 error_buf_size)
@ -741,6 +938,28 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
return NULL; 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 void
wasm_runtime_unload(WASMModuleCommon *module) wasm_runtime_unload(WASMModuleCommon *module)
{ {
@ -768,21 +987,24 @@ wasm_runtime_unload(WASMModuleCommon *module)
} }
WASMModuleInstanceCommon * WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, wasm_runtime_instantiate_internal2(WASMProgramCommon * program,
uint32 stack_size, uint32 heap_size, WASMModuleCommon *module, bool is_sub_inst,
char *error_buf, uint32 error_buf_size) uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
{ {
#if WASM_ENABLE_INTERP != 0 #if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode) if (module->module_type == Wasm_Module_Bytecode)
return (WASMModuleInstanceCommon *)wasm_instantiate( return (WASMModuleInstanceCommon*)
(WASMModule *)module, is_sub_inst, stack_size, heap_size, error_buf, wasm_instantiate((WASMProgramInstance*)program, (WASMModule*)module, is_sub_inst,
error_buf_size); stack_size, heap_size,
error_buf, error_buf_size);
#endif #endif
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT) if (module->module_type == Wasm_Module_AoT)
return (WASMModuleInstanceCommon *)aot_instantiate( return (WASMModuleInstanceCommon*)
(AOTModule *)module, is_sub_inst, stack_size, heap_size, error_buf, aot_instantiate((WASMProgramInstance*)program, (AOTModule*)module, is_sub_inst,
error_buf_size); stack_size, heap_size,
error_buf, error_buf_size);
#endif #endif
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate module failed, invalid module type"); "Instantiate module failed, invalid module type");
@ -790,12 +1012,23 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
} }
WASMModuleInstanceCommon * WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size, wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
uint32 heap_size, char *error_buf, uint32 stack_size, uint32 heap_size,
uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
return wasm_runtime_instantiate_internal( return wasm_runtime_instantiate_internal2(NULL, module, is_sub_inst,
module, false, stack_size, heap_size, error_buf, error_buf_size); 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 void
@ -1053,6 +1286,16 @@ wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
return wasm_exec_env_get_module_inst(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 * void *
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env) wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
{ {
@ -1086,7 +1329,7 @@ wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
#endif #endif
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module_type == Wasm_Module_AoT) { 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 type = aot_func->is_import_func ? aot_func->u.func_import->func_type
: aot_func->u.func.func_type; : aot_func->u.func.func_type;
} }
@ -1179,7 +1422,7 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
#endif #endif
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (exec_env->module_inst->module_type == Wasm_Module_AoT) 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); argv);
#endif #endif
@ -1436,7 +1679,7 @@ wasm_runtime_create_exec_env_and_call_wasm(
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) if (module_inst->module_type == Wasm_Module_AoT)
ret = aot_create_exec_env_and_call_function( ret = aot_create_exec_env_and_call_function(
(AOTModuleInstance *)module_inst, (AOTFunctionInstance *)function, (AOTModuleInstance *)module_inst, (AOTExportFunctionInstance *)function,
argc, argv); argc, argv);
#endif #endif
return ret; return ret;
@ -1506,6 +1749,30 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst)
return NULL; 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 void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst) wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst)
{ {
@ -2246,10 +2513,11 @@ wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) { if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst; AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
AOTFunctionInstance *export_funcs = AOTModule * aot_module = (AOTModule *)aot_inst->aot_module.ptr;
(AOTFunctionInstance *)aot_inst->export_funcs.ptr; AOTExportFunctionInstance *export_funcs = (AOTExportFunctionInstance *)
for (i = 0; i < aot_inst->export_func_count; i++) { aot_inst->export_funcs.ptr;
for (i = 0; i < aot_module->export_func_count; i++) {
if (!strcmp(export_funcs[i].func_name, "_start")) { if (!strcmp(export_funcs[i].func_name, "_start")) {
AOTFuncType *func_type = export_funcs[i].u.func.func_type; AOTFuncType *func_type = export_funcs[i].u.func.func_type;
if (func_type->param_count != 0 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); WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
uint64 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size, arg_i64; 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 *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 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0; uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
bool ret = false; bool ret = false;
@ -3242,6 +3510,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
{ {
arg_i32 = *argv_src++; arg_i32 = *argv_src++;
arg_i64 = arg_i32; arg_i64 = arg_i32;
#if 0
if (signature) { if (signature) {
if (signature[i + 1] == '*') { if (signature[i + 1] == '*') {
/* param is a pointer */ /* param is a pointer */
@ -3269,6 +3538,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
module, arg_i32); module, arg_i32);
} }
} }
#endif
if (n_ints < MAX_REG_INTS) if (n_ints < MAX_REG_INTS)
ints[n_ints++] = arg_i64; ints[n_ints++] = arg_i64;
else else
@ -3376,7 +3646,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
exec_env->attachment = NULL; exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false; ret = !wasm_runtime_get_exception(module) ? true : false;
fail: //fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
wasm_runtime_free(argv1); wasm_runtime_free(argv1);
@ -3719,14 +3989,15 @@ static void
interp_mark_all_externrefs(WASMModuleInstance *module_inst) interp_mark_all_externrefs(WASMModuleInstance *module_inst)
{ {
uint32 i, j, externref_idx, *table_data; uint32 i, j, externref_idx, *table_data;
uint8 *global_data = module_inst->global_data; //uint8 *global_data = module_inst->global_data;
WASMGlobalInstance *global; WASMGlobalInstance *global;
WASMTableInstance *table; WASMTableInstance *table;
global = module_inst->globals; global = module_inst->globals;
for (i = 0; i < module_inst->global_count; i++, global++) { for (i = 0; i < module_inst->global_count; i++, global++) {
if (global->type == VALUE_TYPE_EXTERNREF) { 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); mark_externref(externref_idx);
} }
} }

View File

@ -12,6 +12,7 @@
#include "wasm_native.h" #include "wasm_native.h"
#include "../include/wasm_export.h" #include "../include/wasm_export.h"
#include "../interpreter/wasm.h" #include "../interpreter/wasm.h"
#include "wasm_multimodules_program.h"
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
#if WASM_ENABLE_UVWASI == 0 #if WASM_ENABLE_UVWASI == 0
#include "wasmtime_ssp.h" #include "wasmtime_ssp.h"
@ -25,6 +26,7 @@
extern "C" { extern "C" {
#endif #endif
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
#define PUT_I64_TO_ADDR(addr, value) \ #define PUT_I64_TO_ADDR(addr, value) \
@ -295,6 +297,41 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */ #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 { typedef struct WASMModuleCommon {
/* Module type, for module loaded from WASM bytecode binary, /* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode, and this structure should 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, wasm_runtime_load(const uint8 *buf, uint32 size, char *error_buf,
uint32 error_buf_size); 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 */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleCommon * WASM_RUNTIME_API_EXTERN WASMModuleCommon *
wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot, 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_API_EXTERN void
wasm_runtime_unload(WASMModuleCommon *module); 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 */ /* Internal API */
WASMModuleInstanceCommon * WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
@ -431,6 +494,83 @@ void
wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst, wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst,
bool is_sub_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 */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size, 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_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_get_module_inst(WASMExecEnv *exec_env); 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 */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void * WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env); 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, wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
char *argv[]); char *argv[]);
WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_program_main(WASMProgramCommon *program,
int32 argc, char *argv[]);
/* See wasm_export.h for description */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
const char *name, int32 argc, char *argv[]); 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 */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_exception(WASMModuleInstanceCommon *module, wasm_runtime_set_exception(WASMModuleInstanceCommon *module,
@ -545,6 +696,10 @@ wasm_runtime_set_exception(WASMModuleInstanceCommon *module,
WASM_RUNTIME_API_EXTERN const char * WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_exception(WASMModuleInstanceCommon *module); 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 */ /* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst); wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
@ -629,7 +784,6 @@ void
wasm_runtime_set_llvm_stack(WASMModuleInstanceCommon *module_inst, wasm_runtime_set_llvm_stack(WASMModuleInstanceCommon *module_inst,
uint32 llvm_stack); uint32 llvm_stack);
#if WASM_ENABLE_MULTI_MODULE != 0
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_module_reader(const module_reader reader, wasm_runtime_set_module_reader(const module_reader reader,
const module_destroyer destroyer); const module_destroyer destroyer);
@ -640,6 +794,7 @@ wasm_runtime_get_module_reader();
module_destroyer module_destroyer
wasm_runtime_get_module_destroyer(); wasm_runtime_get_module_destroyer();
#if WASM_ENABLE_MULTI_MODULE != 0
bool bool
wasm_runtime_register_module_internal(const char *module_name, wasm_runtime_register_module_internal(const char *module_name,
WASMModuleCommon *module, WASMModuleCommon *module,
@ -670,6 +825,9 @@ wasm_runtime_destroy_loading_module_list();
bool bool
wasm_runtime_is_built_in_module(const char *module_name); 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 #if WASM_ENABLE_THREAD_MGR != 0
bool bool
wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, 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) { if (module->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module; AOTModuleInstance *aot_inst = (AOTModuleInstance *)module;
AOTMemoryInstance *aot_memory = AOTMemoryInstance *aot_memory =
((AOTMemoryInstance **)aot_inst->memories.ptr)[0]; (AOTMemoryInstance *)aot_inst->memories.ptr;
/* Currently we have only one memory instance */ /* Currently we have only one memory instance */
if (!aot_memory->is_shared) { if (!aot_memory->is_shared) {
wasm_runtime_set_exception(module, "wait on unshared memory"); 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 */ /* Create each memory data segment */
for (i = 0; i < module->data_seg_count; i++) { for (i = 0; i < module->data_seg_count; i++) {
size = offsetof(AOTMemInitData, bytes) size = offsetof(AOTMemInitData, bytes)
+ (uint64)module->data_segments[i]->data_length; + (uint64)module->data_segments[i].data_length;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(data_list[i] = wasm_runtime_malloc((uint32)size))) { || !(data_list[i] = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
@ -69,14 +69,14 @@ aot_create_mem_init_data_list(const WASMModule *module)
} }
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
data_list[i]->is_passive = module->data_segments[i]->is_passive; 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]->memory_index = module->data_segments[i].memory_index;
#endif #endif
data_list[i]->offset = module->data_segments[i]->base_offset; data_list[i]->offset = module->data_segments[i].base_offset;
data_list[i]->byte_count = module->data_segments[i]->data_length; data_list[i]->byte_count = module->data_segments[i].data_length;
memcpy(data_list[i]->bytes, module->data_segments[i]->data, memcpy(data_list[i]->bytes, module->data_segments[i].data,
module->data_segments[i]->data_length); module->data_segments[i].data_length);
} }
return data_list; return data_list;
@ -151,39 +151,43 @@ fail:
static AOTImportGlobal * static AOTImportGlobal *
aot_create_import_globals(const WASMModule *module, 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; AOTImportGlobal *import_globals;
uint64 size; uint64 size;
uint32 i, data_offset = 0; uint32 i, data_offset = 0;
/* Allocate memory */ /* Allocate memory */
size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count; size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(import_globals = wasm_runtime_malloc((uint32)size))) { || !(import_globals = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
} }
memset(import_globals, 0, (uint32)size); memset(import_globals, 0, (uint32)size);
/* Create each import global */ /* Create each import global */
for (i = 0; i < module->import_global_count; i++) { for (i = 0; i < module->import_global_count; i++) {
WASMGlobalImport *import_global = &module->import_globals[i].u.global; WASMGlobalImport *import_global = &module->import_globals[i].u.global;
import_globals[i].module_name = import_global->module_name; import_globals[i].module_name = import_global->module_name;
import_globals[i].global_name = import_global->field_name; import_globals[i].global_name = import_global->field_name;
import_globals[i].type = import_global->type; import_globals[i].type = import_global->type;
import_globals[i].is_mutable = import_global->is_mutable; import_globals[i].is_mutable = import_global->is_mutable;
import_globals[i].global_data_linked = import_globals[i].global_data_linked = import_global->global_data_linked;
import_global->global_data_linked; // patch for mutable global
import_globals[i].size = wasm_value_type_size(import_global->type); if (!import_globals[i].is_mutable)
/* Calculate data offset */ import_globals[i].size = wasm_value_type_size(import_global->type);
import_globals[i].data_offset = data_offset; else
data_offset += wasm_value_type_size(import_global->type); import_globals[i].size = pointer_size;
} /* Calculate data offset */
import_globals[i].data_offset = data_offset;
data_offset += import_globals[i].size;
}
*p_import_global_data_size = data_offset; *p_import_global_data_size = data_offset;
return import_globals; return import_globals;
} }
static AOTGlobal * static AOTGlobal *
@ -306,25 +310,20 @@ aot_create_import_funcs(const WASMModule *module)
} }
static void 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); wasm_runtime_free(funcs);
} }
static AOTFunc ** static AOTFunc *
aot_create_funcs(const WASMModule *module) aot_create_funcs(const WASMModule *module)
{ {
AOTFunc **funcs; AOTFunc *funcs = NULL;
uint64 size; uint64 size;
uint32 i, j; uint32 i, j;
/* Allocate memory */ /* 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))) { if (size >= UINT32_MAX || !(funcs = wasm_runtime_malloc((uint32)size))) {
aot_set_last_error("allocate memory failed."); aot_set_last_error("allocate memory failed.");
return NULL; return NULL;
@ -335,39 +334,30 @@ aot_create_funcs(const WASMModule *module)
/* Create each function */ /* Create each function */
for (i = 0; i < module->function_count; i++) { for (i = 0; i < module->function_count; i++) {
WASMFunction *func = module->functions[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 */ /* Resolve function type index */
for (j = 0; j < module->type_count; j++) for (j = 0; j < module->type_count; j++)
if (func->func_type == module->types[j]) { if (func->func_type == module->types[j]) {
funcs[i]->func_type_index = j; funcs[i].func_type_index = j;
break; break;
} }
/* Resolve local variable info and code info */ /* Resolve local variable info and code info */
funcs[i]->local_count = func->local_count; funcs[i].local_count = func->local_count;
funcs[i]->local_types = func->local_types; funcs[i].local_types = func->local_types;
funcs[i]->param_cell_num = func->param_cell_num; funcs[i].param_cell_num = func->func_type->param_cell_num;
funcs[i]->local_cell_num = func->local_cell_num; funcs[i].local_cell_num = func->local_cell_num;
funcs[i]->code = func->code; funcs[i].code = func->code;
funcs[i]->code_size = func->code_size; funcs[i].code_size = func->code_size;
} }
return funcs; return funcs;
fail:
aot_destroy_funcs(funcs, module->function_count);
return NULL;
} }
AOTCompData * AOTCompData*
aot_create_comp_data(WASMModule *module) aot_create_comp_data(WASMModule *module, uint32 pointer_size)
{ {
AOTCompData *comp_data; AOTCompData *comp_data;
uint32 import_global_data_size = 0, global_data_size = 0, i, j; uint32 import_global_data_size = 0, global_data_size = 0, i, j;
@ -479,24 +469,25 @@ aot_create_comp_data(WASMModule *module)
comp_data->table_init_data_count = module->table_seg_count; comp_data->table_init_data_count = module->table_seg_count;
if (comp_data->table_init_data_count > 0 if (comp_data->table_init_data_count > 0
&& !(comp_data->table_init_data_list = && !(comp_data->table_init_data_list =
aot_create_table_init_data_list(module))) aot_create_table_init_data_list(module)))
goto fail; goto fail;
/* Create import globals */ /* Create import globals */
comp_data->import_global_count = module->import_global_count; comp_data->import_global_count = module->import_global_count;
if (comp_data->import_global_count > 0 if (comp_data->import_global_count > 0
&& !(comp_data->import_globals = && !(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; goto fail;
/* Create globals */ /* Create globals */
comp_data->global_count = module->global_count; comp_data->global_count = module->global_count;
if (comp_data->global_count if (comp_data->global_count
&& !(comp_data->globals = aot_create_globals( && !(comp_data->globals = aot_create_globals
module, import_global_data_size, &global_data_size))) (module, import_global_data_size, &global_data_size)))
goto fail; 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 */ /* Create function types */
comp_data->func_type_count = module->type_count; comp_data->func_type_count = module->type_count;
@ -512,14 +503,15 @@ aot_create_comp_data(WASMModule *module)
/* Create functions */ /* Create functions */
comp_data->func_count = module->function_count; 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; goto fail;
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0 #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
/* Create custom name section */ /* Create custom name section */
comp_data->name_section_buf = module->name_section_buf; comp_data->name_section_buf = module->name_section_buf;
comp_data->name_section_buf_end = module->name_section_buf_end; comp_data->name_section_buf_end = module->name_section_buf_end;
#endif #endif
/* Create aux data/heap/stack information */ /* Create aux data/heap/stack information */
comp_data->aux_data_end_global_index = module->aux_data_end_global_index; comp_data->aux_data_end_global_index = module->aux_data_end_global_index;

View File

@ -15,11 +15,15 @@
extern "C" { extern "C" {
#endif #endif
#define AOT_FEATURE_ENABLE_DYNAMIC_LINKING 0x1
#define AOT_FEATURE_ENABLE_XIP_MODE (0x1 << 1)
#define AOT_FUNC_PREFIX "aot_func#" #define AOT_FUNC_PREFIX "aot_func#"
typedef InitializerExpression AOTInitExpr; typedef InitializerExpression AOTInitExpr;
typedef WASMType AOTFuncType; typedef WASMType AOTFuncType;
typedef WASMExport AOTExport; typedef WASMExport AOTExport;
struct AOTCompContext;
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
typedef void *dwar_extractor_handle_t; typedef void *dwar_extractor_handle_t;
@ -136,16 +140,16 @@ typedef struct AOTTableInitData {
* Import global variable * Import global variable
*/ */
typedef struct AOTImportGlobal { typedef struct AOTImportGlobal {
char *module_name; const ConstStrDescription *module_name;
char *global_name; const ConstStrDescription *global_name;
/* VALUE_TYPE_I32/I64/F32/F64 */ /* VALUE_TYPE_I32/I64/F32/F64 */
uint8 type; uint8 type;
bool is_mutable; bool is_mutable;
uint32 size; uint32 size;
/* The data offset of current global in global data */ /* The data offset of current global in global data */
uint32 data_offset; uint32 data_offset;
/* global data after linked */ /* global data after linked */
WASMValue global_data_linked; WASMValue global_data_linked;
} AOTImportGlobal; } AOTImportGlobal;
/** /**
@ -165,19 +169,19 @@ typedef struct AOTGlobal {
* Import function * Import function
*/ */
typedef struct AOTImportFunc { typedef struct AOTImportFunc {
char *module_name; const ConstStrDescription * module_name;
char *func_name; const ConstStrDescription *func_name;
AOTFuncType *func_type; AOTFuncType *func_type;
uint32 func_type_index; uint32 func_type_index;
/* function pointer after linked */ /* function pointer after linked */
void *func_ptr_linked; void *func_ptr_linked;
/* signature from registered native symbols */ /* signature from registered native symbols */
const char *signature; const char *signature;
/* attachment */ /* attachment */
void *attachment; void *attachment;
bool call_conv_raw; bool call_conv_raw;
bool call_conv_wasm_c_api; bool call_conv_wasm_c_api;
bool wasm_c_api_with_env; bool wasm_c_api_with_env;
} AOTImportFunc; } AOTImportFunc;
/** /**
@ -237,7 +241,7 @@ typedef struct AOTCompData {
/* Functions */ /* Functions */
uint32 func_count; uint32 func_count;
AOTFunc **funcs; AOTFunc * funcs;
/* Custom name sections */ /* Custom name sections */
const uint8 *name_section_buf; const uint8 *name_section_buf;
@ -272,8 +276,8 @@ typedef struct AOTNativeSymbol {
int32 index; int32 index;
} AOTNativeSymbol; } AOTNativeSymbol;
AOTCompData * AOTCompData*
aot_create_comp_data(WASMModule *module); aot_create_comp_data(WASMModule *module, uint32 pointer_size);
void void
aot_destroy_comp_data(AOTCompData *comp_data); 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; 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()); set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail2; 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()); set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail3; 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)) { if (!aot_compile_wasm(comp_ctx)) {
set_error_buf(error_buf, error_buf_size, aot_get_last_error()); set_error_buf(error_buf, error_buf_size, aot_get_last_error());
goto fail4; 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; *p_aot_file_size = aot_file_size;
fail4: fail4:
/* Destroy compile data */
aot_destroy_comp_data(comp_data);
fail3:
/* Destroy compiler context */ /* Destroy compiler context */
aot_destroy_comp_context(comp_ctx); aot_destroy_comp_context(comp_ctx);
fail3:
/* Destroy compile data */
aot_destroy_comp_data(comp_data);
fail2: fail2:
wasm_unload(wasm_module); wasm_unload(wasm_module);
fail1: fail1:

View File

@ -173,7 +173,7 @@ static uint32
get_file_header_size() get_file_header_size()
{ {
/* magic number (4 bytes) + version (4 bytes) */ /* magic number (4 bytes) + version (4 bytes) */
return sizeof(uint32) + sizeof(uint32); return sizeof(uint32) + sizeof(uint32) + sizeof(uint64) + sizeof(uint32);
} }
static 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 */ /* type (1 byte) + is_mutable (1 byte) + module_name + global_name */
uint32 size = (uint32)sizeof(uint8) * 2 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 = 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; return size;
} }
@ -463,9 +464,10 @@ get_import_func_size(AOTCompContext *comp_ctx, AOTImportFunc *import_func)
{ {
/* type index (2 bytes) + module_name + func_name */ /* type index (2 bytes) + module_name + func_name */
uint32 size = (uint32)sizeof(uint16) 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 = 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; return size;
} }
@ -521,12 +523,38 @@ get_object_data_section_info_size(AOTCompContext *comp_ctx,
obj_data->data_sections_count); 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 static uint32
get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data, get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTObjectData *obj_data) AOTObjectData *obj_data)
{ {
uint32 size = 0; uint32 size = 0;
size = align_uint(size, 4);
size += get_mem_info_size(comp_data); size += get_mem_info_size(comp_data);
size = align_uint(size, 4); 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 += (uint32)sizeof(uint32) * 2;
size += get_target_info_section_size(); 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 */ /* init data section */
size = align_uint(size, 4); size = align_uint(size, 4);
/* section id + section size */ /* 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 offset = *p_offset;
uint32 aot_curr_version = AOT_CURRENT_VERSION; 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('\0');
EMIT_U8('a'); EMIT_U8('a');
@ -1285,6 +1325,13 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U8('t'); EMIT_U8('t');
EMIT_U32(aot_curr_version); 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; *p_offset = offset;
return true; return true;
@ -1484,9 +1531,9 @@ aot_emit_import_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
offset = align_uint(offset, 2); offset = align_uint(offset, 2);
EMIT_U8(import_global->type); EMIT_U8(import_global->type);
EMIT_U8(import_global->is_mutable); EMIT_U8(import_global->is_mutable);
EMIT_STR(import_global->module_name); EMIT_STR(import_global->module_name->str);
offset = align_uint(offset, 2); offset = align_uint(offset, 2);
EMIT_STR(import_global->global_name); EMIT_STR(import_global->global_name->str);
} }
if (offset - *p_offset 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++) { for (i = 0; i < comp_data->import_func_count; i++, import_func++) {
offset = align_uint(offset, 2); offset = align_uint(offset, 2);
EMIT_U16(import_func->func_type_index); 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); 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)) { 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; 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 static bool
aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset, aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompContext *comp_ctx, AOTCompData *comp_data, 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 section_size = get_func_section_size(comp_data, obj_data);
uint32 i, offset = *p_offset; uint32 i, offset = *p_offset;
AOTObjectFunc *func = obj_data->funcs; AOTObjectFunc *func = obj_data->funcs;
AOTFunc **funcs = comp_data->funcs; AOTFunc *funcs = comp_data->funcs;
*p_offset = offset = align_uint(offset, 4); *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++) 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) { if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
aot_set_last_error("emit function section failed."); 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; buf_end = buf + aot_file_size;
if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data) if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_target_info_section(buf, buf_end, &offset, comp_data, || !aot_emit_target_info_section(buf, buf_end, &offset, comp_data, obj_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, || !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx, comp_data, obj_data)
comp_data, obj_data)
|| !aot_emit_text_section(buf, buf_end, &offset, 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_func_section(buf, buf_end, &offset, comp_data, obj_data)
|| !aot_emit_export_section(buf, buf_end, &offset, comp_ctx, comp_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, LLVMPositionBuilderAtEnd(comp_ctx->builder,
func_ctx->got_exception_block); func_ctx->got_exception_block);
/* Create exection id phi */ /* Create exception id phi */
if (!(func_ctx->exception_id_phi = LLVMBuildPhi( if (!(func_ctx->exception_id_phi = LLVMBuildPhi(
comp_ctx->builder, I32_TYPE, "exception_id_phi"))) { comp_ctx->builder, I32_TYPE, "exception_id_phi"))) {
aot_set_last_error("llvm build phi failed."); 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, compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 global_idx, bool is_set, bool is_aux_stack) uint32 global_idx, bool is_set, bool is_aux_stack)
{ {
WASMRuntime * runtime = wasm_runtime_get_runtime();
AOTCompData *comp_data = comp_ctx->comp_data; AOTCompData *comp_data = comp_ctx->comp_data;
uint32 import_global_count = comp_data->import_global_count; uint32 import_global_count = comp_data->import_global_count;
uint32 global_base_offset = uint32 global_base_offset =
@ -116,8 +117,8 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ sizeof(AOTMemoryInstance) * comp_ctx->comp_data->memory_count; + sizeof(AOTMemoryInstance) * comp_ctx->comp_data->memory_count;
uint32 global_offset; uint32 global_offset;
uint8 global_type; uint8 global_type;
LLVMValueRef offset, global_ptr, global, res; LLVMValueRef offset, global_ptr_ptr, global_ptr, global, res;
LLVMTypeRef ptr_type = NULL; LLVMTypeRef ptr_type = NULL, mutable_ptr_type = NULL;
bh_assert(global_idx < import_global_count + comp_data->global_count); bh_assert(global_idx < import_global_count + comp_data->global_count);
@ -164,10 +165,46 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
break; break;
} }
if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr, ptr_type, // check if import mutable global
"global_ptr"))) { if (!(global_idx < import_global_count &&
aot_set_last_error("llvm build bit cast failed."); comp_data->import_globals[global_idx].is_mutable &&
return false; 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 (!is_set) {

View File

@ -902,7 +902,7 @@ aot_create_func_contexts(AOTCompData *comp_data, AOTCompContext *comp_ctx)
/* Create each function context */ /* Create each function context */
for (i = 0; i < comp_data->func_count; i++) { 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] = if (!(func_ctxes[i] =
aot_create_func_context(comp_data, comp_ctx, func, i))) { aot_create_func_context(comp_data, comp_ctx, func, i))) {
aot_destroy_func_contexts(func_ctxes, comp_data->func_count); aot_destroy_func_contexts(func_ctxes, comp_data->func_count);
@ -1363,8 +1363,28 @@ fail:
} }
#endif /* WASM_ENABLE_LAZY_JIT != 0 */ #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 * 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; AOTCompContext *comp_ctx, *ret = NULL;
#if WASM_ENABLE_LAZY_JIT == 0 #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)); memset(comp_ctx, 0, sizeof(AOTCompContext));
comp_ctx->comp_data = comp_data;
/* Create LLVM context, module and builder */ /* Create LLVM context, module and builder */
#if WASM_ENABLE_LAZY_JIT != 0 #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* */ /* set aot_inst data type to int8* */
comp_ctx->aot_inst_type = INT8_PTR_TYPE; 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) { if (cpu) {
uint32 len = (uint32)strlen(cpu) + 1; uint32 len = (uint32)strlen(cpu) + 1;
if (!(comp_ctx->target_cpu = wasm_runtime_malloc(len))) { 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 */ /* Call the LLVM intrinsic function */
if (!(ret = LLVMBuildCall(comp_ctx->builder, func, param_values, 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."); aot_set_last_error("llvm build intrinsic call failed.");
return NULL; return NULL;
} }
@ -2351,15 +2363,15 @@ aot_call_llvm_intrinsic(const AOTCompContext *comp_ctx,
LLVMTypeRef ret_type, LLVMTypeRef *param_types, LLVMTypeRef ret_type, LLVMTypeRef *param_types,
int param_count, ...) int param_count, ...)
{ {
LLVMValueRef *param_values, ret; LLVMValueRef *param_values = NULL, ret = NULL;
va_list argptr; va_list argptr;
uint64 total_size; uint64 total_size;
int i = 0; int i = 0;
/* Create param values */ /* Create param values */
total_size = sizeof(LLVMValueRef) * (uint64)param_count; total_size = sizeof(LLVMValueRef) * (uint64)param_count;
if (total_size >= UINT32_MAX if (total_size > 0 && (total_size >= UINT32_MAX
|| !(param_values = wasm_runtime_malloc((uint32)total_size))) { || !(param_values = wasm_runtime_malloc((uint32)total_size)))) {
aot_set_last_error("allocate memory for param values failed."); aot_set_last_error("allocate memory for param values failed.");
return false; 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, ret = __call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, ret_type,
param_types, param_count, param_values); param_types, param_count, param_values);
wasm_runtime_free(param_values); if (param_values)
wasm_runtime_free(param_values);
return ret; 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 LLVMValueRef
aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx, aot_call_llvm_intrinsic_v(const AOTCompContext *comp_ctx,
const AOTFuncContext *func_ctx, const char *intrinsic, const AOTFuncContext *func_ctx, const char *intrinsic,

View File

@ -366,8 +366,14 @@ typedef struct AOTCompOption {
uint32 bounds_checks; uint32 bounds_checks;
} AOTCompOption, *aot_comp_option_t; } 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 * AOTCompContext *
aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option); aot_create_comp_context(aot_comp_option_t option);
void void
aot_destroy_comp_context(AOTCompContext *comp_ctx); aot_destroy_comp_context(AOTCompContext *comp_ctx);
@ -442,6 +448,9 @@ LLVMValueRef
aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base, aot_get_func_from_table(const AOTCompContext *comp_ctx, LLVMValueRef base,
LLVMTypeRef func_type, int32 index); LLVMTypeRef func_type, int32 index);
void
aot_call_debugtrap_intrinsic(const AOTCompContext *comp_ctx, const AOTFuncContext *func_ctx);
bool bool
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str); 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; typedef struct AOTCompContext *aot_comp_context_t;
aot_comp_data_t aot_comp_data_t
aot_create_comp_data(void *wasm_module); aot_create_comp_data(void *wasm_module, uint32 pointer_size);
void void
aot_destroy_comp_data(aot_comp_data_t comp_data); aot_destroy_comp_data(aot_comp_data_t comp_data);
@ -61,8 +61,14 @@ typedef struct AOTCompOption {
uint32_t bounds_checks; uint32_t bounds_checks;
} AOTCompOption, *aot_comp_option_t; } 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_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 void
aot_destroy_comp_context(aot_comp_context_t comp_ctx); aot_destroy_comp_context(aot_comp_context_t comp_ctx);

View File

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

View File

@ -63,6 +63,10 @@ struct WASMModuleCommon;
typedef struct WASMModuleCommon *wasm_module_t; typedef struct WASMModuleCommon *wasm_module_t;
#endif #endif
/* Instantiated multiple module program */
struct WASMProgramCommon;
typedef struct WASMProgramCommon *wasm_program_t;
/* Instantiated WASM module */ /* Instantiated WASM module */
struct WASMModuleInstanceCommon; struct WASMModuleInstanceCommon;
typedef struct WASMModuleInstanceCommon *wasm_module_inst_t; typedef struct WASMModuleInstanceCommon *wasm_module_inst_t;
@ -138,6 +142,8 @@ typedef struct RuntimeInitArgs {
int platform_port; int platform_port;
int instance_port; int instance_port;
#endif #endif
bool standalone;
bool auto_ext_name;
} RuntimeInitArgs; } RuntimeInitArgs;
#ifndef WASM_VALKIND_T_DEFINED #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, wasm_runtime_load(const uint8_t *buf, uint32_t size,
char *error_buf, uint32_t error_buf_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. * 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_API_EXTERN void
wasm_runtime_unload(wasm_module_t module); 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_API_EXTERN void
wasm_runtime_set_wasi_args_ex(wasm_module_t module, 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_API_EXTERN wasm_module_inst_t
wasm_runtime_get_module_inst(wasm_exec_env_t exec_env); 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 * Call the given WASM function of a WASM module instance with
* arguments (bytecode and AoT). * arguments (bytecode and AoT).
@ -523,6 +546,10 @@ WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_main(wasm_module_inst_t module_inst, wasm_application_execute_main(wasm_module_inst_t module_inst,
int32_t argc, char *argv[]); 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 * Find the specified function in argv[0] from a WASM module instance
* and execute that function. * and execute that function.
@ -541,6 +568,10 @@ wasm_application_execute_main(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN bool WASM_RUNTIME_API_EXTERN bool
wasm_application_execute_func(wasm_module_inst_t module_inst, wasm_application_execute_func(wasm_module_inst_t module_inst,
const char *name, int32_t argc, char *argv[]); 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. * 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_API_EXTERN const char *
wasm_runtime_get_exception(wasm_module_inst_t module_inst); 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. * Set exception info of the WASM module instance.
* *

View File

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

View File

@ -22,7 +22,6 @@ typedef float32 CellType_F32;
typedef float64 CellType_F64; typedef float64 CellType_F64;
#define BR_TABLE_TMP_BUF_LEN 32 #define BR_TABLE_TMP_BUF_LEN 32
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
do { \ do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \ uint64 offset1 = (uint64)offset + (uint64)addr; \
@ -342,17 +341,18 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
#define RECOVER_FRAME_IP_END() (void)0 #define RECOVER_FRAME_IP_END() (void)0
#endif #endif
#define RECOVER_CONTEXT(new_frame) \ #define RECOVER_CONTEXT(new_frame) \
do { \ do { \
frame = (new_frame); \ frame = (new_frame); \
cur_func = frame->function; \ cur_func = frame->function; \
prev_frame = frame->prev_frame; \ cur_func_type = cur_func->func_type; \
frame_ip = frame->ip; \ prev_frame = frame->prev_frame; \
RECOVER_FRAME_IP_END(); \ frame_ip = frame->ip; \
frame_lp = frame->lp; \ RECOVER_FRAME_IP_END(); \
frame_sp = frame->sp; \ frame_lp = frame->lp; \
frame_csp = frame->csp; \ frame_sp = frame->sp; \
} while (0) frame_csp = frame->csp; \
} while (0)
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define GET_OPCODE() opcode = *(frame_ip - 1); #define GET_OPCODE() opcode = *(frame_ip - 1);
@ -571,12 +571,12 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
#define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \ #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
do { \ 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); \ read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
bh_assert(local_idx < param_count + cur_func->local_count); \ bh_assert(local_idx < param_count + cur_func->local_count); \
local_offset = cur_func->local_offsets[local_idx]; \ local_offset = cur_func->local_offsets[local_idx]; \
if (local_idx < param_count) \ if (local_idx < param_count) \
local_type = cur_func->param_types[local_idx]; \ local_type = cur_func_type->types[local_idx]; \
else \ else \
local_type = cur_func->local_types[local_idx - param_count]; \ local_type = cur_func->local_types[local_idx - param_count]; \
} while (0) } while (0)
@ -759,6 +759,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMFunctionImport *func_import = cur_func->u.func_import; WASMFunctionImport *func_import = cur_func->u.func_import;
WASMType * func_type = func_import->func_type;
unsigned local_cell_num = 2; unsigned local_cell_num = 2;
WASMInterpFrame *frame; WASMInterpFrame *frame;
uint32 argv_ret[2]; uint32 argv_ret[2];
@ -779,17 +780,17 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
if (!func_import->func_ptr_linked) { if (!func_import->func_ptr_linked) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)", "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); wasm_set_exception(module_inst, buf);
return; return;
} }
if (func_import->call_conv_wasm_c_api) { if (func_import->call_conv_wasm_c_api) {
ret = wasm_runtime_invoke_c_api_native( ret = wasm_runtime_invoke_c_api_native(
(WASMModuleInstanceCommon *)module_inst, (WASMModuleInstanceCommon *)module_inst,
func_import->func_ptr_linked, func_import->func_type, 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); func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) { if (ret) {
argv_ret[0] = frame->lp[0]; argv_ret[0] = frame->lp[0];
argv_ret[1] = frame->lp[1]; argv_ret[1] = frame->lp[1];
@ -799,23 +800,23 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
ret = wasm_runtime_invoke_native( ret = wasm_runtime_invoke_native(
exec_env, func_import->func_ptr_linked, func_import->func_type, exec_env, func_import->func_ptr_linked, func_import->func_type,
func_import->signature, func_import->attachment, frame->lp, func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret); func_type->param_cell_num, argv_ret);
} }
else { else {
ret = wasm_runtime_invoke_native_raw( 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_import->func_type,
func_import->signature, func_import->attachment, frame->lp, func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret); func_type->param_cell_num, argv_ret);
} }
if (!ret) if (!ret)
return; 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[0] = argv_ret[0];
prev_frame->sp++; 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[0] = argv_ret[0];
prev_frame->sp[1] = argv_ret[1]; prev_frame->sp[1] = argv_ret[1];
prev_frame->sp += 2; 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); wasm_exec_env_set_cur_frame(exec_env, prev_frame);
} }
#if WASM_ENABLE_MULTI_MODULE != 0
static void static void
wasm_interp_call_func_bytecode(WASMModuleInstance *module, wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMExecEnv *exec_env, WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame); 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 static void
wasm_interp_call_func_import(WASMModuleInstance *module_inst, wasm_interp_call_func_import(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env, WASMExecEnv *exec_env,
@ -847,7 +883,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
if (!sub_func_inst) { if (!sub_func_inst) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)", "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); wasm_set_exception(module_inst, buf);
return; return;
} }
@ -948,15 +984,19 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */ #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
static inline uint8 * static inline uint8 *
get_global_addr(uint8 *global_data, WASMGlobalInstance *global) get_global_addr(WASMGlobalInstance *global)
{ {
#if WASM_ENABLE_MULTI_MODULE == 0 #if WASM_ENABLE_MULTI_MODULE == 0
return global_data + global->data_offset; //return global_data + global->data_offset;
return global->data;
#else #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 return global->import_global_inst
? global->import_module_inst->global_data ? global->import_global_inst->data
+ global->import_global_inst->data_offset : global->data;
: global_data + global->data_offset;
#endif #endif
} }
@ -966,32 +1006,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *memory = module->default_memory;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data; //#if WASM_ENABLE_MULTI_MODULE == 1
uint32 linear_mem_size = //uint8 *global_data = module->global_data;
memory ? num_bytes_per_page * memory->cur_page_count : 0; //#endif
WASMType **wasm_types = module->module->types; uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMGlobalInstance *globals = module->globals, *global; WASMType **wasm_types = module->module->types;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP; WASMGlobalInstance *globals = module->globals, *global;
WASMInterpFrame *frame = NULL; uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
/* Points to this special opcode so as to jump to the WASMInterpFrame *frame = NULL;
* call_method_from_entry. */ #if WASM_ENABLE_DYNAMIC_LINKING != 0
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */ WASMProgramInstance * program = module->program;
register uint32 *frame_lp = NULL; /* cache of frame->lp */ #endif
register uint32 *frame_sp = NULL; /* cache of frame->sp */ WASMModuleInstance * callee_module_inst = NULL;
WASMBranchBlock *frame_csp = NULL; WASMType * cur_func_type = cur_func->func_type;
BlockAddr *cache_items; /* Points to this special opcode so as to jump to the call_method_from_entry. */
uint8 *frame_ip_end = frame_ip + 1; register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
uint8 opcode; register uint32 *frame_lp = NULL; /* cache of frame->lp */
uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0; register uint32 *frame_sp = NULL; /* cache of frame->sp */
uint64 all_cell_num = 0; WASMBranchBlock *frame_csp = NULL;
int32 val; BlockAddr *cache_items;
uint8 *else_addr, *end_addr, *maddr = NULL; uint8 *frame_ip_end = frame_ip + 1;
uint32 local_idx, local_offset, global_idx; uint8 opcode;
uint8 local_type, *global_addr; uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0;
uint32 cache_index, type_index, cell_num; uint64 all_cell_num = 0;
uint8 value_type; int32 val;
uint8 *else_addr, *end_addr, *maddr = NULL;
uint32 local_idx, local_offset, global_idx;
uint8 local_type, *global_addr;
uint32 cache_index, type_index, cell_num;
uint8 value_type;
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
@ -1131,8 +1176,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
POP_CSP(); POP_CSP();
} }
else { /* end of function, treat as WASM_OP_RETURN */ else { /* end of function, treat as WASM_OP_RETURN */
frame_sp -= cur_func->ret_cell_num; frame_sp -= cur_func_type->ret_cell_num;
for (i = 0; i < cur_func->ret_cell_num; i++) { for (i = 0; i < cur_func_type->ret_cell_num; i++) {
*prev_frame->sp++ = frame_sp[i]; *prev_frame->sp++ = frame_sp[i];
} }
goto return_func; goto return_func;
@ -1190,8 +1235,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_RETURN) HANDLE_OP(WASM_OP_RETURN)
{ {
frame_sp -= cur_func->ret_cell_num; frame_sp -= cur_func_type->ret_cell_num;
for (i = 0; i < cur_func->ret_cell_num; i++) { for (i = 0; i < cur_func_type->ret_cell_num; i++) {
*prev_frame->sp++ = frame_sp[i]; *prev_frame->sp++ = frame_sp[i];
} }
goto return_func; goto return_func;
@ -1211,6 +1256,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#endif #endif
cur_func = module->functions + fidx; 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; goto call_func_from_interp;
} }
@ -1228,7 +1280,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
#endif #endif
cur_func = module->functions + fidx; cur_func = module->functions + fidx;
cur_func_type = cur_func->func_type;
goto call_func_from_return_call; goto call_func_from_return_call;
} }
#endif /* WASM_ENABLE_TAIL_CALL */ #endif /* WASM_ENABLE_TAIL_CALL */
@ -1237,10 +1289,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT) HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
#endif #endif
{ {
WASMType *cur_type, *cur_func_type; WASMType *cur_type;
WASMTableInstance *tbl_inst; uint32 tbl_idx;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
#endif #endif
@ -1248,60 +1300,78 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_SUSPEND_FLAGS(); CHECK_SUSPEND_FLAGS();
#endif #endif
/** /**
* type check. compiler will make sure all like * type check. compiler will make sure all like
* (call_indirect (type $x) (i32.const 1)) * (call_indirect (type $x) (i32.const 1))
* the function type has to be defined in the module also * the function type has to be defined in the module also
* no matter it is used or not * no matter it is used or not
*/ */
read_leb_uint32(frame_ip, frame_ip_end, tidx); read_leb_uint32(frame_ip, frame_ip_end, tidx);
bh_assert(tidx < module->module->type_count); bh_assert(tidx < module->module->type_count);
cur_type = wasm_types[tidx]; cur_type = wasm_types[tidx];
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
bh_assert(tbl_idx < module->table_count); 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;
}
val = POP_I32(); cur_func_type = cur_func->func_type;
if (val < 0 || val >= (int32)tbl_inst->cur_size) { #else
wasm_set_exception(module, "undefined element"); WASMTableInstance *tbl_inst;
goto got_exception; callee_module_inst = module;
} tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
fidx = ((uint32 *)tbl_inst->base_addr)[val]; if (val < 0 || val >= (int32)tbl_inst->cur_size) {
if (fidx == (uint32)-1) { wasm_set_exception(module, "undefined element");
wasm_set_exception(module, "uninitialized element"); goto got_exception;
goto got_exception; }
}
/* fidx = ((uint32*)tbl_inst->base_addr)[val];
* we might be using a table injected by host or if (fidx == (uint32)-1) {
* another module. In that case, we don't validate wasm_set_exception(module, "uninitialized element");
* the elem value while loading goto got_exception;
*/ }
if (fidx >= module->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
/* always call module own functions */ /*
cur_func = module->functions + fidx; * we might be using a table injected by host or
* another module. In that case, we don't validate
* the elem value while loading
*/
if (fidx >= callee_module_inst->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
if (cur_func->is_import_func) /* always call module own functions */
cur_func_type = cur_func->u.func_import->func_type; cur_func = callee_module_inst->functions + fidx;
else cur_func_type = cur_func->func_type;
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) { if (!wasm_type_equal(cur_type, cur_func_type)) {
wasm_set_exception(module, "indirect call type mismatch"); wasm_set_exception(module, "indirect call type mismatch");
goto got_exception; goto got_exception;
} }
#if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;
#endif #endif
goto call_func_from_interp;
} #if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;
#endif
goto call_func_from_interp;
}
/* parametric instructions */ /* parametric instructions */
HANDLE_OP(WASM_OP_DROP) HANDLE_OP(WASM_OP_DROP)
@ -1549,7 +1619,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
PUSH_I32(*(uint32 *)global_addr); PUSH_I32(*(uint32 *)global_addr);
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -1559,7 +1629,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; 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)); PUSH_I64(GET_I64_FROM_ADDR((uint32 *)global_addr));
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -1569,7 +1639,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
*(int32 *)global_addr = POP_I32(); *(int32 *)global_addr = POP_I32();
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -1581,7 +1651,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; 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); aux_stack_top = *(uint32 *)(frame_sp - 1);
if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) { if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
wasm_set_exception(module, "wasm auxiliary stack overflow"); 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); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; 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()); PUT_I64_TO_ADDR((uint32 *)global_addr, POP_I64());
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2914,9 +2984,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
seg_len = (uint64)module->module->data_segments[segment] seg_len = (uint64)module->module->data_segments[segment].data_length;
->data_length; data = module->module->data_segments[segment].data;
data = module->module->data_segments[segment]->data;
if (offset + bytes > seg_len) if (offset + bytes > seg_len)
goto out_of_bounds; goto out_of_bounds;
@ -2929,7 +2998,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 segment; uint32 segment;
read_leb_uint32(frame_ip, frame_ip_end, 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; break;
} }
@ -3079,6 +3148,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
+ offsetof(WASMTableInstance, base_addr) + offsetof(WASMTableInstance, base_addr)
+ s * sizeof(uint32), + s * sizeof(uint32),
(uint32)(n * 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; break;
} }
case WASM_OP_TABLE_GROW: case WASM_OP_TABLE_GROW:
@ -3562,8 +3635,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
call_func_from_return_call: call_func_from_return_call:
{ {
POP(cur_func->param_cell_num); POP(cur_func_type->param_cell_num);
word_copy(frame->lp, frame_sp, cur_func->param_cell_num); word_copy(frame->lp, frame_sp, cur_func_type->param_cell_num);
FREE_FRAME(exec_env, frame); FREE_FRAME(exec_env, frame);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
goto call_func_from_entry; goto call_func_from_entry;
@ -3573,29 +3646,56 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
/* Only do the copy when it's called from interpreter. */ /* Only do the copy when it's called from interpreter. */
WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env); 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(); 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; prev_frame = frame;
} }
call_func_from_entry: 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 (cur_func->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
if (cur_func->import_func_inst) { if (cur_func->import_func_inst) {
wasm_interp_call_func_import(module, exec_env, cur_func, wasm_interp_call_func_import(module, exec_env, cur_func,
prev_frame); prev_frame);
} }
else else
#endif #endif
{ {
wasm_interp_call_func_native(module, exec_env, cur_func, wasm_interp_call_func_native(module, exec_env, cur_func,
prev_frame); prev_frame);
} }
prev_frame = frame->prev_frame; prev_frame = frame->prev_frame;
cur_func = frame->function; cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME(); UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */ /* update memory instance ptr and memory size */
@ -3607,11 +3707,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
else { else {
WASMFunction *cur_wasm_func = cur_func->u.func; WASMFunction *cur_wasm_func = cur_func->u.func;
WASMType *func_type;
func_type = cur_wasm_func->func_type; all_cell_num = (uint64)cur_func_type->param_cell_num
all_cell_num = (uint64)cur_func->param_cell_num
+ (uint64)cur_func->local_cell_num + (uint64)cur_func->local_cell_num
+ (uint64)cur_wasm_func->max_stack_cell_num + (uint64)cur_wasm_func->max_stack_cell_num
+ ((uint64)cur_wasm_func->max_block_num) + ((uint64)cur_wasm_func->max_block_num)
@ -3634,7 +3731,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_lp = frame->lp; frame_lp = frame->lp;
frame_sp = frame->sp_bottom = 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_boundary =
frame->sp_bottom + cur_wasm_func->max_stack_cell_num; 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; frame->csp_bottom + cur_wasm_func->max_block_num;
/* Initialize the local variables */ /* 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)); (uint32)(cur_func->local_cell_num * 4));
/* Push function block as first block */ /* 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); PUSH_CSP(LABEL_TYPE_FUNCTION, cell_num, frame_ip_end - 1);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame);
@ -3656,6 +3753,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_SUSPEND_FLAGS(); CHECK_SUSPEND_FLAGS();
#endif #endif
} }
}
HANDLE_OP_END(); 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); WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
WASMInterpFrame *frame, *outs_area; WASMInterpFrame *frame, *outs_area;
WASMType * func_type = function->func_type;
/* Allocate sufficient cells for all kinds of return values. */ /* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num = 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; i;
/* This frame won't be used by JITed code, so only allocate interp /* This frame won't be used by JITed code, so only allocate interp
frame here. */ frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); 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]; char buf[128];
snprintf(buf, sizeof(buf), "invalid argument count %d, expected %d", 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); wasm_set_exception(module_inst, buf);
return; return;
} }
@ -3757,8 +3856,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* Output the return value to the caller */ /* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) { 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->sp + i - function->ret_cell_num); argv[i] = *(frame->sp + i - func_type->ret_cell_num);
} }
} }
else { else {

View File

@ -228,12 +228,12 @@ LOAD_PTR(void *addr)
#define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \ #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() \
do { \ do { \
uint32 param_count = cur_func->param_count; \ uint32 param_count = cur_func_type->param_count; \
local_idx = read_uint32(frame_ip); \ local_idx = read_uint32(frame_ip); \
bh_assert(local_idx < param_count + cur_func->local_count); \ bh_assert(local_idx < param_count + cur_func->local_count); \
local_offset = cur_func->local_offsets[local_idx]; \ local_offset = cur_func->local_offsets[local_idx]; \
if (local_idx < param_count) \ if (local_idx < param_count) \
local_type = cur_func->param_types[local_idx]; \ local_type = cur_func_type->types[local_idx]; \
else \ else \
local_type = cur_func->local_types[local_idx - param_count]; \ local_type = cur_func->local_types[local_idx - param_count]; \
} while (0) } while (0)
@ -318,14 +318,15 @@ LOAD_PTR(void *addr)
#define UPDATE_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func) #define UPDATE_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func)
#endif #endif
#define RECOVER_CONTEXT(new_frame) \ #define RECOVER_CONTEXT(new_frame) \
do { \ do { \
frame = (new_frame); \ frame = (new_frame); \
cur_func = frame->function; \ cur_func = frame->function; \
prev_frame = frame->prev_frame; \ cur_func_type = cur_func->func_type;\
frame_ip = frame->ip; \ prev_frame = frame->prev_frame; \
UPDATE_FRAME_IP_END(); \ frame_ip = frame->ip; \
frame_lp = frame->lp; \ UPDATE_FRAME_IP_END(); \
frame_lp = frame->lp; \
} while (0) } while (0)
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
@ -830,6 +831,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMFunctionImport *func_import = cur_func->u.func_import; WASMFunctionImport *func_import = cur_func->u.func_import;
WASMType * func_type = cur_func->func_type;
unsigned local_cell_num = 2; unsigned local_cell_num = 2;
WASMInterpFrame *frame; WASMInterpFrame *frame;
uint32 argv_ret[2]; uint32 argv_ret[2];
@ -850,16 +852,16 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
char buf[128]; char buf[128];
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)", "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); wasm_set_exception((WASMModuleInstance*)module_inst, buf);
return; return;
} }
if (func_import->call_conv_wasm_c_api) { if (func_import->call_conv_wasm_c_api) {
ret = wasm_runtime_invoke_c_api_native( ret = wasm_runtime_invoke_c_api_native(
(WASMModuleInstanceCommon *)module_inst, (WASMModuleInstanceCommon *)module_inst,
func_import->func_ptr_linked, func_import->func_type, func_import->func_ptr_linked, 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); func_import->wasm_c_api_with_env, func_import->attachment);
if (ret) { if (ret) {
argv_ret[0] = frame->lp[0]; 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) { else if (!func_import->call_conv_raw) {
ret = wasm_runtime_invoke_native( 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, func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret); func_type->param_cell_num, argv_ret);
} }
else { else {
ret = wasm_runtime_invoke_native_raw( 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, func_import->signature, func_import->attachment, frame->lp,
cur_func->param_cell_num, argv_ret); func_type->param_cell_num, argv_ret);
} }
if (!ret) if (!ret)
return; 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]; 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] = argv_ret[0];
prev_frame->lp[prev_frame->ret_offset + 1] = argv_ret[1]; 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); wasm_exec_env_set_cur_frame(exec_env, prev_frame);
} }
#if WASM_ENABLE_MULTI_MODULE != 0
static void static void
wasm_interp_call_func_bytecode(WASMModuleInstance *module, wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMExecEnv *exec_env, WASMExecEnv *exec_env,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame); 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 static void
wasm_interp_call_func_import(WASMModuleInstance *module_inst, wasm_interp_call_func_import(WASMModuleInstance *module_inst,
WASMExecEnv *exec_env, WASMExecEnv *exec_env,
@ -916,7 +953,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
if (!sub_func_inst) { if (!sub_func_inst) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"failed to call unlinked import function (%s, %s)", "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); wasm_set_exception(module_inst, buf);
return; return;
} }
@ -1029,15 +1066,19 @@ static void **global_handle_table;
#endif #endif
static inline uint8 * static inline uint8 *
get_global_addr(uint8 *global_data, WASMGlobalInstance *global) get_global_addr(WASMGlobalInstance *global)
{ {
#if WASM_ENABLE_MULTI_MODULE == 0 #if WASM_ENABLE_MULTI_MODULE == 0
return global_data + global->data_offset; //return global_data + global->data_offset;
return global->data;
#else #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 return global->import_global_inst
? global->import_module_inst->global_data ? global->import_global_inst->data
+ global->import_global_inst->data_offset : global->data;
: global_data + global->data_offset;
#endif #endif
} }
@ -1047,18 +1088,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *memory = module->default_memory;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data; //#if WASM_ENABLE_MULTI_MODULE == 1
uint32 linear_mem_size = // uint8 *global_data = module->global_data;
memory ? num_bytes_per_page * memory->cur_page_count : 0; //#endif
WASMGlobalInstance *globals = module->globals, *global; uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP; WASMGlobalInstance *globals = module->globals, *global;
WASMInterpFrame *frame = NULL; uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
/* Points to this special opcode so as to jump to the WASMInterpFrame *frame = NULL;
* call_method_from_entry. */ #if WASM_ENABLE_DYNAMIC_LINKING != 0
register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */ WASMProgramInstance * program = module->program;
register uint32 *frame_lp = NULL; /* cache of frame->lp */ #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 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
/* cache of label base addr */ /* cache of label base addr */
@ -1084,6 +1130,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
#endif #endif
cur_func_type = cur_func->func_type;
#if WASM_ENABLE_LABELS_AS_VALUES == 0 #if WASM_ENABLE_LABELS_AS_VALUES == 0
while (frame_ip < frame_ip_end) { while (frame_ip < frame_ip_end) {
opcode = *frame_ip++; opcode = *frame_ip++;
@ -1222,10 +1270,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT) HANDLE_OP(WASM_OP_RETURN_CALL_INDIRECT)
#endif #endif
{ {
WASMType *cur_type, *cur_func_type; WASMType *cur_type;
WASMTableInstance *tbl_inst; uint32 tbl_idx;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
GET_OPCODE(); GET_OPCODE();
@ -1234,49 +1281,69 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_SUSPEND_FLAGS(); CHECK_SUSPEND_FLAGS();
#endif #endif
tidx = read_uint32(frame_ip); tidx = read_uint32(frame_ip);
cur_type = module->module->types[tidx]; cur_type = module->module->types[tidx];
tbl_idx = read_uint32(frame_ip); tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count); 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;
val = GET_OPERAND(uint32, I32, 0); #if WASM_ENABLE_DYNAMIC_LINKING != 0
frame_ip += 2; 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;
}
if (val < 0 || val >= (int32)tbl_inst->cur_size) { cur_func_type = cur_func->func_type;
wasm_set_exception(module, "undefined element"); #else
goto got_exception; WASMTableInstance *tbl_inst;
} callee_module_inst = module;
tbl_inst = wasm_get_table_inst(module, tbl_idx);
fidx = ((uint32 *)tbl_inst->base_addr)[val]; if (val < 0 ||
if (fidx == (uint32)-1) { (val >= (int32)tbl_inst->cur_size
wasm_set_exception(module, "uninitialized element"); )) {
goto got_exception; wasm_set_exception(module, "undefined element");
} goto got_exception;
}
/* fidx = ((uint32*)tbl_inst->base_addr)[val];
* we might be using a table injected by host or if (fidx == (uint32)-1) {
* another module. in that case, we don't validate wasm_set_exception(module, "uninitialized element");
* the elem value while loading goto got_exception;
*/ }
if (fidx >= module->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
/* always call module own functions */ /*
cur_func = module->functions + fidx; * we might be using a table injected by host or
* another module. in that case, we don't validate
* the elem value while loading
*/
if (fidx >= callee_module_inst->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
/* always call module own functions */
cur_func = callee_module_inst->functions + fidx;
cur_func_type = cur_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 (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;
}
#if WASM_ENABLE_TAIL_CALL != 0 #if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT) if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call; goto call_func_from_return_call;
@ -1427,7 +1494,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip); global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
addr_ret = GET_OFFSET(); addr_ret = GET_OFFSET();
frame_lp[addr_ret] = *(uint32 *)global_addr; frame_lp[addr_ret] = *(uint32 *)global_addr;
HANDLE_OP_END(); HANDLE_OP_END();
@ -1438,7 +1505,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip); global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
addr_ret = GET_OFFSET(); addr_ret = GET_OFFSET();
PUT_I64_TO_ADDR(frame_lp + addr_ret, PUT_I64_TO_ADDR(frame_lp + addr_ret,
GET_I64_FROM_ADDR((uint32 *)global_addr)); GET_I64_FROM_ADDR((uint32 *)global_addr));
@ -1450,7 +1517,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip); global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
addr1 = GET_OFFSET(); addr1 = GET_OFFSET();
*(int32 *)global_addr = frame_lp[addr1]; *(int32 *)global_addr = frame_lp[addr1];
HANDLE_OP_END(); HANDLE_OP_END();
@ -1463,7 +1530,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global_idx = read_uint32(frame_ip); global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; 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()]; aux_stack_top = frame_lp[GET_OFFSET()];
if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) { if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
wasm_set_exception(module, "wasm auxiliary stack overflow"); 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); global_idx = read_uint32(frame_ip);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global);
addr1 = GET_OFFSET(); addr1 = GET_OFFSET();
PUT_I64_TO_ADDR((uint32 *)global_addr, PUT_I64_TO_ADDR((uint32 *)global_addr,
GET_I64_FROM_ADDR(frame_lp + addr1)); 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); CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
seg_len = (uint64)module->module->data_segments[segment] seg_len = (uint64)module->module->data_segments[segment].data_length;
->data_length; data = module->module->data_segments[segment].data;
data = module->module->data_segments[segment]->data;
if (offset + bytes > seg_len) if (offset + bytes > seg_len)
goto out_of_bounds; goto out_of_bounds;
@ -2861,7 +2927,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
segment = read_uint32(frame_ip); segment = read_uint32(frame_ip);
module->module->data_segments[segment]->data_length = 0; module->module->data_segments[segment].data_length = 0;
break; break;
} }
@ -3004,6 +3070,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
+ offsetof(WASMTableInstance, base_addr) + offsetof(WASMTableInstance, base_addr)
+ s * sizeof(uint32), + s * sizeof(uint32),
(uint32)(n * 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; break;
} }
case WASM_OP_TABLE_GROW: case WASM_OP_TABLE_GROW:
@ -3426,6 +3496,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
#endif #endif
cur_func = module->functions + fidx; 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; goto call_func_from_interp;
} }
@ -3443,6 +3550,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
#endif #endif
cur_func = module->functions + fidx; cur_func = module->functions + fidx;
cur_func_type = cur_func->func_type;
goto call_func_from_return_call; goto call_func_from_return_call;
} }
#endif /* WASM_ENABLE_TAIL_CALL */ #endif /* WASM_ENABLE_TAIL_CALL */
@ -3522,22 +3630,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 *lp; uint32 *lp;
int i; 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)))) { * sizeof(uint32)))) {
wasm_set_exception(module, "allocate memory failed"); wasm_set_exception(module, "allocate memory failed");
goto got_exception; goto got_exception;
} }
for (i = 0; i < cur_func->param_count; i++) { for (i = 0; i < cur_func_type->param_count; i++) {
if (cur_func->param_types[i] == VALUE_TYPE_I64 if (cur_func_type->types[i] == VALUE_TYPE_I64
|| cur_func->param_types[i] == VALUE_TYPE_F64) { || cur_func->types[i] == VALUE_TYPE_F64) {
PUT_I64_TO_ADDR( PUT_I64_TO_ADDR(
lp, GET_OPERAND(uint64, I64, lp, GET_OPERAND(uint64, I64,
2 * (cur_func->param_count - i - 1))); 2 * (cur_func_type->param_count - i - 1)));
lp += 2; lp += 2;
} }
else { else {
*lp = GET_OPERAND(uint32, I32, *lp = GET_OPERAND(uint32, I32,
(2 * (cur_func->param_count - i - 1))); (2 * (cur_func_type->param_count - i - 1)));
lp++; lp++;
} }
} }
@ -3545,7 +3653,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
word_copy(frame->lp, lp_base, lp - lp_base); word_copy(frame->lp, lp_base, lp - lp_base);
wasm_runtime_free(lp_base); wasm_runtime_free(lp_base);
FREE_FRAME(exec_env, frame); 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); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
goto call_func_from_entry; 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; outs_area->lp = outs_area->operand + cur_func->const_cell_num;
} }
for (i = 0; i < cur_func->param_count; i++) { for (i = 0; i < cur_func_type->param_count; i++) {
if (cur_func->param_types[i] == VALUE_TYPE_I64 if (cur_func_type->types[i] == VALUE_TYPE_I64
|| cur_func->param_types[i] == VALUE_TYPE_F64) { || cur_func_type->types[i] == VALUE_TYPE_F64) {
PUT_I64_TO_ADDR( PUT_I64_TO_ADDR(
outs_area->lp, outs_area->lp,
GET_OPERAND(uint64, I64, GET_OPERAND(uint64, I64,
2 * (cur_func->param_count - i - 1))); 2 * (cur_func_type->param_count - i - 1)));
outs_area->lp += 2; outs_area->lp += 2;
} }
else { else {
*outs_area->lp = GET_OPERAND( *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++; outs_area->lp++;
} }
} }
frame_ip += cur_func->param_count * sizeof(int16); frame_ip += cur_func_type->param_count * sizeof(int16);
if (cur_func->ret_cell_num != 0) { if (cur_func_type->ret_cell_num != 0) {
/* Get the first return value's offset. Since loader emit /* Get the first return value's offset. Since loader emit
* all return values' offset so we must skip remain return * all return values' offset so we must skip remain return
* values' offsets. * values' offsets.
@ -3604,21 +3712,46 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
call_func_from_entry: 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 (cur_func->is_import_func) {
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
if (cur_func->import_func_inst) { if (cur_func->import_func_inst) {
wasm_interp_call_func_import(module, exec_env, cur_func, wasm_interp_call_func_import(module, exec_env, cur_func,
prev_frame); prev_frame);
} }
else else
#endif #endif
{ {
wasm_interp_call_func_native(module, exec_env, cur_func, wasm_interp_call_func_native(module, exec_env, cur_func,
prev_frame); prev_frame);
} }
prev_frame = frame->prev_frame; prev_frame = frame->prev_frame;
cur_func = frame->function; cur_func = frame->function;
cur_func_type = cur_func->func_type;
UPDATE_ALL_FROM_FRAME(); UPDATE_ALL_FROM_FRAME();
/* update memory instance ptr and memory size */ /* update memory instance ptr and memory size */
@ -3629,42 +3762,42 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
else { else {
WASMFunction *cur_wasm_func = cur_func->u.func; 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->local_cell_num
+ (uint64)cur_func->const_cell_num + (uint64)cur_func->const_cell_num
+ (uint64)cur_wasm_func->max_stack_cell_num; + (uint64)cur_wasm_func->max_stack_cell_num;
if (all_cell_num >= UINT32_MAX) { if (all_cell_num >= UINT32_MAX) {
wasm_set_exception(module, "wasm operand stack overflow"); wasm_set_exception(module, "wasm operand stack overflow");
goto got_exception; goto got_exception;
} }
frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num); frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) { if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
frame = prev_frame; frame = prev_frame;
goto got_exception; goto got_exception;
} }
/* Initialize the interpreter context. */ /* Initialize the interpreter context. */
frame->function = cur_func; frame->function = cur_func;
frame_ip = wasm_get_func_code(cur_func); frame_ip = wasm_get_func_code(cur_func);
frame_ip_end = wasm_get_func_code_end(cur_func); frame_ip_end = wasm_get_func_code_end(cur_func);
frame_lp = frame->lp = frame_lp = frame->lp = frame->operand + cur_wasm_func->const_cell_num;
frame->operand + cur_wasm_func->const_cell_num;
/* Initialize the consts */ /* Initialize the consts */
word_copy(frame->operand, (uint32 *)cur_wasm_func->consts, word_copy(frame->operand, (uint32*)cur_wasm_func->consts,
cur_wasm_func->const_cell_num); cur_wasm_func->const_cell_num);
/* Initialize the local variables */ /* 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)); (uint32)(cur_func->local_cell_num * 4));
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame);
} }
HANDLE_OP_END(); }
HANDLE_OP_END ();
} }
return_func: return_func:
@ -3680,7 +3813,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP_END(); HANDLE_OP_END();
} }
(void)frame_ip_end; (void)frame_ip_end;
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
unaligned_atomic: unaligned_atomic:
@ -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); WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
WASMInterpFrame *frame, *outs_area; WASMInterpFrame *frame, *outs_area;
WASMType * func_type = function->func_type;
/* Allocate sufficient cells for all kinds of return values. */ /* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num = 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; i;
/* This frame won't be used by JITed code, so only allocate interp /* This frame won't be used by JITed code, so only allocate interp
frame here. */ frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); 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]; char buf[128];
snprintf(buf, sizeof(buf), "invalid argument count %d, expected %d", 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); wasm_set_exception(module_inst, buf);
return; return;
} }
@ -3780,7 +3914,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* Output the return value to the caller */ /* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) { 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); argv[i] = *(frame->lp + i);
} }
else { else {

View File

@ -20,6 +20,9 @@
#define TEMPLATE_READ_VALUE(Type, p) \ #define TEMPLATE_READ_VALUE(Type, p) \
(p += sizeof(Type), *(Type *)(p - sizeof(Type))) (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 static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) 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); 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 static bool
load_init_expr(const uint8 **p_buf, const uint8 *buf_end, load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, char *error_buf, InitializerExpression *init_expr, uint8 type, char *error_buf,
@ -1018,15 +960,17 @@ delete_loading_module:
static bool static bool
load_function_import(const uint8 **p_buf, const uint8 *buf_end, load_function_import(const uint8 **p_buf, const uint8 *buf_end,
const WASMModule *parent_module, const WASMModule *parent_module,
const char *sub_module_name, const char *function_name, const ConstStrDescription *sub_module_name,
WASMFunctionImport *function, char *error_buf, const ConstStrDescription *function_name,
uint32 error_buf_size) WASMFunctionImport *function,
char *error_buf, uint32 error_buf_size)
{ {
const uint8 *p = *p_buf, *p_end = buf_end; const uint8 *p = *p_buf, *p_end = buf_end;
uint32 declare_type_index = 0; uint32 declare_type_index = 0;
WASMType *declare_func_type = NULL; WASMType *declare_func_type = NULL;
WASMFunction *linked_func = NULL; WASMFunction *linked_func = NULL;
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
WASMRuntime * runtime = parent_module->runtime;
WASMModule *sub_module = NULL; WASMModule *sub_module = NULL;
#endif #endif
const char *linked_signature = NULL; 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]; declare_func_type = parent_module->types[declare_type_index];
/* lookup registered native symbols first */ /* lookup registered native symbols first */
linked_func = wasm_native_resolve_symbol( linked_func = wasm_native_resolve_symbol(sub_module_name,
sub_module_name, function_name, declare_func_type, &linked_signature, &function_name,
&linked_attachment, &linked_call_conv_raw); declare_func_type,
&linked_signature,
&linked_attachment,
&linked_call_conv_raw);
if (linked_func) { if (linked_func) {
is_native_symbol = true; is_native_symbol = true;
} }
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
else { else {
if (!wasm_runtime_is_built_in_module(sub_module_name)) { if (!wasm_runtime_is_built_in_module_new(runtime, sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name, sub_module = load_depended_module(parent_module, (char*)sub_module_name->str,
error_buf, error_buf_size); error_buf, error_buf_size);
if (!sub_module) { if (!sub_module) {
return false; return false;
} }
} }
linked_func = wasm_loader_resolve_function( linked_func = wasm_loader_resolve_function((char*)sub_module_name->str,
sub_module_name, function_name, declare_func_type, error_buf, (char*)function_name->str,
error_buf_size); declare_func_type,
error_buf,
error_buf_size);
} }
#endif #endif
function->module_name = (char *)sub_module_name; function->module_name = sub_module_name;
function->field_name = (char *)function_name; function->field_name = function_name;
function->func_type = declare_func_type; function->func_type = declare_func_type;
/* func_ptr_linked is for native registered symbol */ /* func_ptr_linked is for native registered symbol */
function->func_ptr_linked = is_native_symbol ? linked_func : NULL; function->func_ptr_linked = is_native_symbol ? linked_func : NULL;
@ -1343,9 +1292,11 @@ fail:
static bool static bool
load_global_import(const uint8 **p_buf, const uint8 *buf_end, load_global_import(const uint8 **p_buf, const uint8 *buf_end,
const WASMModule *parent_module, char *sub_module_name, const WASMModule *parent_module,
char *global_name, WASMGlobalImport *global, char *error_buf, const ConstStrDescription *sub_module_name,
uint32 error_buf_size) const ConstStrDescription *global_name,
WASMGlobalImport *global,
char *error_buf, uint32 error_buf_size)
{ {
const uint8 *p = *p_buf, *p_end = buf_end; const uint8 *p = *p_buf, *p_end = buf_end;
uint8 declare_type = 0; 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 #if WASM_ENABLE_LIBC_BUILTIN != 0
global->is_linked = wasm_native_lookup_libc_builtin_global( 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->is_linked) {
if (global->type != declare_type if (global->type != declare_type
|| global->is_mutable != declare_mutable) { || global->is_mutable != declare_mutable) {
@ -1379,17 +1331,18 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
#endif #endif
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
if (!global->is_linked if (!global->is_linked
&& !wasm_runtime_is_built_in_module(sub_module_name)) { && !wasm_runtime_is_built_in_module((char*)sub_module_name->str)) {
sub_module = load_depended_module(parent_module, sub_module_name, sub_module = load_depended_module(parent_module, (char*)sub_module_name->str,
error_buf, error_buf_size); error_buf, error_buf_size);
if (!sub_module) { if (!sub_module) {
return false; return false;
} }
/* check sub modules */ /* check sub modules */
linked_global = wasm_loader_resolve_global( linked_global =
sub_module_name, global_name, declare_type, declare_mutable, wasm_loader_resolve_global((char*)sub_module_name->str, (char*)global_name->str,
error_buf, error_buf_size); declare_type, declare_mutable,
error_buf, error_buf_size);
if (linked_global) { if (linked_global) {
global->import_module = sub_module; global->import_module = sub_module;
global->import_global_linked = linked_global; global->import_global_linked = linked_global;
@ -1548,7 +1501,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
WASMImport *import; WASMImport *import;
WASMImport *import_functions = NULL, *import_tables = NULL; WASMImport *import_functions = NULL, *import_tables = NULL;
WASMImport *import_memories = NULL, *import_globals = 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; uint8 u8, kind;
read_leb_uint32(p, p_end, import_count); 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 */ /* load module name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(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, if (!(sub_module_name = wasm_runtime_records_const_string(module->runtime,
error_buf_size))) { (const char*)p, name_len, error_buf, error_buf_size))) {
return false; return false;
} }
p += name_len; p += name_len;
/* load field name */ /* load field name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(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, if (!(field_name = wasm_runtime_records_const_string(module->runtime,
error_buf_size))) { (const char*)p, name_len, error_buf, error_buf_size))) {
return false; return false;
} }
p += name_len; p += name_len;
CHECK_BUF(p, p_end, 1); 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 */ case IMPORT_KIND_TABLE: /* import table */
bh_assert(import_tables); bh_assert(import_tables);
import = import_tables++; import = import_tables++;
if (!load_table_import(&p, p_end, module, sub_module_name, if (!load_table_import(&p, p_end, module,
field_name, &import->u.table, (char*)sub_module_name->str, (char*)field_name->str,
&import->u.table,
error_buf, error_buf_size)) { error_buf, error_buf_size)) {
LOG_DEBUG("can not import such a table (%s,%s)", LOG_DEBUG("can not import such a table (%s,%s)",
sub_module_name, field_name); (char*)sub_module_name->str, field_name);
return false; return false;
} }
break; break;
@ -1698,8 +1655,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
case IMPORT_KIND_MEMORY: /* import memory */ case IMPORT_KIND_MEMORY: /* import memory */
bh_assert(import_memories); bh_assert(import_memories);
import = import_memories++; import = import_memories++;
if (!load_memory_import(&p, p_end, module, sub_module_name, if (!load_memory_import(&p, p_end, module,
field_name, &import->u.memory, (char*)sub_module_name->str, (char*)field_name->str,
&import->u.memory,
error_buf, error_buf_size)) { error_buf, error_buf_size)) {
return false; return false;
} }
@ -1728,9 +1686,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
import = module->import_functions; import = module->import_functions;
for (i = 0; i < module->import_function_count; i++, import++) { for (i = 0; i < module->import_function_count; i++, import++) {
if (!strcmp(import->u.names.module_name, "wasi_unstable") if (!strcmp((char*)import->u.names.module_name->str, "wasi_unstable")
|| !strcmp(import->u.names.module_name, || !strcmp((char*)import->u.names.module_name->str, "wasi_snapshot_preview1")) {
"wasi_snapshot_preview1")) {
module->is_wasi_module = true; module->is_wasi_module = true;
break; break;
} }
@ -1785,7 +1742,7 @@ init_function_local_offsets(WASMFunction *func, char *error_buf,
local_offset += wasm_value_type_cell_num(local_types[i]); 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; 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 = func->local_cell_num =
wasm_get_cell_num(func->local_types, func->local_count); 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; uint32 str_len;
WASMExport *export; WASMExport *export;
const char *name; const char *name;
const ConstStrDescription * key_export_name = NULL;
read_leb_uint32(p, p_end, export_count); 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( key_export_name = wasm_runtime_records_const_string(module->runtime,
p, str_len, module, is_load_from_file_buf, error_buf, (const char*)p, str_len, error_buf, error_buf_size);
error_buf_size))) { if (!key_export_name) {
return false; return false;
} }
export->name = key_export_name->str;
p += str_len; p += str_len;
CHECK_BUF(p, p_end, 1); CHECK_BUF(p, p_end, 1);
@ -2190,6 +2148,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
report error */ report error */
#endif #endif
#endif #endif
module->export_func_count ++;
break; break;
/* table index */ /* table index */
case EXPORT_KIND_TABLE: case EXPORT_KIND_TABLE:
@ -2199,6 +2158,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown table"); "unknown table");
return false; return false;
} }
module->export_tab_count++;
break; break;
/* memory index */ /* memory index */
case EXPORT_KIND_MEMORY: case EXPORT_KIND_MEMORY:
@ -2208,6 +2168,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown memory"); "unknown memory");
return false; return false;
} }
module->export_mem_count++;
break; break;
/* global index */ /* global index */
case EXPORT_KIND_GLOBAL: case EXPORT_KIND_GLOBAL:
@ -2217,6 +2178,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
"unknown global"); "unknown global");
return false; return false;
} }
module->export_global_count++;
break; break;
default: default:
set_error_buf(error_buf, error_buf_size, 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) { if (data_seg_count) {
module->data_seg_count = data_seg_count; module->data_seg_count = data_seg_count;
total_size = sizeof(WASMDataSeg *) * (uint64)data_seg_count; total_size = sizeof(WASMDataSeg) * (uint64)data_seg_count;
if (!(module->data_segments = if (!(module->data_segments = loader_malloc
loader_malloc(total_size, error_buf, error_buf_size))) { (total_size, error_buf, error_buf_size))) {
return false; 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); read_leb_uint32(p, p_end, data_seg_len);
if (!(dataseg = module->data_segments[i] = loader_malloc( dataseg = &module->data_segments[i];
sizeof(WASMDataSeg), error_buf, error_buf_size))) {
return false;
}
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
dataseg->is_passive = is_passive; 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 previous_func_index = ~0U;
uint32 func_name_len; uint32 func_name_len;
uint32 name_index; uint32 name_index;
const ConstStrDescription * key_func_name = NULL;
int i = 0; int i = 0;
if (p >= p_end) { 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); read_leb_uint32(p, p_end, func_name_len);
CHECK_BUF(p, p_end, func_name_len); CHECK_BUF(p, p_end, func_name_len);
/* Skip the import functions */ /* Skip the import functions */
if (func_index >= module->import_count) { if (func_index >= module->import_function_count) {
func_index -= module->import_count; func_index -= module->import_function_count;
if (func_index >= module->function_count) { if (func_index >= module->function_count) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"out-of-range function index"); "out-of-range function index");
return false; return false;
} }
if (!(module->functions[func_index]->field_name = key_func_name = wasm_runtime_records_const_string(module->runtime,
const_str_list_insert( (const char*)p, func_name_len, error_buf, error_buf_size);
p, func_name_len, module, if (!key_func_name) {
is_load_from_file_buf, error_buf,
error_buf_size))) {
return false; return false;
} }
module->functions[func_index]->field_name = key_func_name->str;
} }
p += func_name_len; p += func_name_len;
} }
@ -2785,6 +2744,184 @@ fail:
} }
#endif #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 static bool
load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
bool is_load_from_file_buf, char *error_buf, 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, handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
error_buf_size); 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 #endif
LOG_VERBOSE("Load custom section success.\n"); LOG_VERBOSE("Load custom section success.\n");
return true; return true;
@ -3226,6 +3371,14 @@ create_module(char *error_buf, uint32 error_buf_size)
#endif #endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
bh_list_init(&module->fast_opcode_list); 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 #endif
return module; return module;
} }
@ -3512,22 +3665,19 @@ wasm_loader_unload(WASMModule *module)
} }
if (module->data_segments) { 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); wasm_runtime_free(module->data_segments);
} }
if (module->const_str_list) { #if WASM_ENABLE_DYNAMIC_LINKING != 0
StringNode *node = module->const_str_list, *node_next; if (module->dylink_section) {
while (node) { wasm_runtime_free(module->dylink_section);
node_next = node->next;
wasm_runtime_free(node);
node = node_next;
}
} }
if (module->implicit_dependency_modules_hmap) {
bh_hash_map_destroy(module->implicit_dependency_modules_hmap);
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
/* just release the sub module list */ /* just release the sub module list */
if (module->import_module_list) { if (module->import_module_list) {
@ -3559,6 +3709,10 @@ wasm_loader_unload(WASMModule *module)
fast_opcode = next; fast_opcode = next;
} }
#endif #endif
if (module->file_buf)
wasm_runtime_free((void*)module->file_buf);
wasm_runtime_free(module); 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); memset(loader_ctx->const_buf, 0, loader_ctx->const_buf_size);
loader_ctx->start_dynamic_offset = loader_ctx->dynamic_offset = loader_ctx->start_dynamic_offset = loader_ctx->dynamic_offset =
loader_ctx->max_dynamic_offset = loader_ctx->max_dynamic_offset = func->func_type->param_cell_num +
func->param_cell_num + func->local_cell_num; func->local_cell_num;
#endif #endif
return loader_ctx; 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]); 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; 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 = func->local_cell_num =
wasm_get_cell_num(func->local_types, func->local_count); 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 */ /* mutable or constant */
bool is_mutable; bool is_mutable;
/* data offset to base_addr of WASMMemoryInstance */ /* data offset to base_addr of WASMMemoryInstance */
uint32 data_offset; uint8 * data;
// uint32 data_offset;
/* initial value */ /* initial value */
WASMValue initial_value; WASMValue initial_value;
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
@ -91,16 +92,17 @@ struct WASMGlobalInstance {
}; };
struct WASMFunctionInstance { struct WASMFunctionInstance {
/* the owner module instance */
WASMModuleInstance * module_inst;
/* whether it is import function or WASM function */ /* whether it is import function or WASM function */
bool is_import_func; bool is_import_func;
/* parameter count */
uint16 param_count; /* function signature*/
WASMType * func_type;
/* local variable count, 0 for import function */ /* local variable count, 0 for import function */
uint16 local_count; 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 */ /* cell num of local variables, 0 for import function */
uint16 local_cell_num; uint16 local_cell_num;
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
@ -108,15 +110,14 @@ struct WASMFunctionInstance {
uint16 const_cell_num; uint16 const_cell_num;
#endif #endif
uint16 *local_offsets; uint16 *local_offsets;
/* parameter types */
uint8 *param_types;
/* local types, NULL for import function */ /* local types, NULL for import function */
uint8 *local_types; uint8 *local_types;
union { union {
WASMFunctionImport *func_import; WASMFunctionImport *func_import;
WASMFunction *func; WASMFunction *func;
} u; } u;
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
WASMModuleInstance *import_module_inst; WASMModuleInstance *import_module_inst;
WASMFunctionInstance *import_func_inst; WASMFunctionInstance *import_func_inst;
#endif #endif
@ -129,13 +130,13 @@ struct WASMFunctionInstance {
}; };
typedef struct WASMExportFuncInstance { typedef struct WASMExportFuncInstance {
char *name; const char * name;
WASMFunctionInstance *function; WASMFunctionInstance *function;
} WASMExportFuncInstance; } WASMExportFuncInstance;
#if WASM_ENABLE_MULTI_MODULE != 0 //#if WASM_ENABLE_MULTI_MODULE != 0
typedef struct WASMExportGlobInstance { typedef struct WASMExportGlobInstance {
char *name; const char *name;
WASMGlobalInstance *global; WASMGlobalInstance *global;
} WASMExportGlobInstance; } WASMExportGlobInstance;
@ -148,7 +149,7 @@ typedef struct WASMExportMemInstance {
char *name; char *name;
WASMMemoryInstance *memory; WASMMemoryInstance *memory;
} WASMExportMemInstance; } WASMExportMemInstance;
#endif //#endif
struct WASMModuleInstance { struct WASMModuleInstance {
/* Module instance type, for module instance loaded from /* Module instance type, for module instance loaded from
@ -157,14 +158,26 @@ struct WASMModuleInstance {
Wasm_Module_AoT, and this structure should be treated as Wasm_Module_AoT, and this structure should be treated as
AOTModuleInstance structure. */ AOTModuleInstance structure. */
uint32 module_type; 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 memory_count;
uint32 table_count; uint32 table_count;
uint32 global_count; uint32 global_count;
uint32 function_count; uint32 function_count;
uint32 export_func_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_glob_count;
uint32 export_mem_count; uint32 export_mem_count;
uint32 export_tab_count; uint32 export_tab_count;
@ -176,7 +189,7 @@ struct WASMModuleInstance {
WASMFunctionInstance *functions; WASMFunctionInstance *functions;
WASMExportFuncInstance *export_functions; WASMExportFuncInstance *export_functions;
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
WASMExportGlobInstance *export_globals; WASMExportGlobInstance *export_globals;
WASMExportMemInstance *export_memories; WASMExportMemInstance *export_memories;
WASMExportTabInstance *export_tables; WASMExportTabInstance *export_tables;
@ -289,8 +302,16 @@ void
wasm_unload(WASMModule *module); wasm_unload(WASMModule *module);
WASMModuleInstance * WASMModuleInstance *
wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, wasm_instantiate(WASMProgramInstance * program,
uint32 heap_size, char *error_buf, uint32 error_buf_size); 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 void
wasm_dump_perf_profiling(const WASMModuleInstance *module_inst); wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
@ -413,11 +434,11 @@ wasm_elem_is_declarative(uint32 mode)
{ {
return (mode & 0x3) == 0x3; return (mode & 0x3) == 0x3;
} }
#endif /* WASM_ENABLE_REF_TYPES != 0 */
bool bool
wasm_enlarge_table(WASMModuleInstance *module_inst, uint32 table_idx, wasm_enlarge_table(WASMModuleInstance *module_inst, uint32 table_idx,
uint32 inc_entries, uint32 init_val); uint32 inc_entries, uint32 init_val);
#endif /* WASM_ENABLE_REF_TYPES != 0 */
static inline WASMTableInstance * static inline WASMTableInstance *
wasm_get_table_inst(const WASMModuleInstance *module_inst, const uint32 tbl_idx) wasm_get_table_inst(const WASMModuleInstance *module_inst, const uint32 tbl_idx)

View File

@ -16,6 +16,9 @@
#define get_module(exec_env) \ #define get_module(exec_env) \
wasm_exec_env_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) \ #define get_module_inst(exec_env) \
wasm_runtime_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, posix_memalign_wrapper(wasm_exec_env_t exec_env, void **memptr, int32 align,
int32 size) 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; void *p = NULL;
*((int32 *)memptr) = module_malloc(size, (void **)&p); *((int32 *)memptr) = module_malloc(size, (void **)&p);

View File

@ -5,6 +5,7 @@
#include "bh_common.h" #include "bh_common.h"
#include "bh_log.h" #include "bh_log.h"
#include "ConstStrDesc.h"
#include "wasm_export.h" #include "wasm_export.h"
#include "../interpreter/wasm.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) \ #define get_module_inst(exec_env) \
wasm_runtime_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) \ #define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
struct str_context ctx = { NULL, 0, 0 }; struct str_context ctx = { NULL, 0, 0 };
/* format has been checked by runtime */ if (!validate_app_str_addr((uint32)(uintptr_t)format))
if (!validate_native_addr(va_args, sizeof(int32)))
return 0; 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)) module_inst))
return 0; return 0;
@ -479,33 +489,50 @@ printf_wrapper(wasm_exec_env_t exec_env, const char *format, _va_list va_args)
} }
static int static int
sprintf_wrapper(wasm_exec_env_t exec_env, char *str, const char *format, iprintf_wrapper(wasm_exec_env_t exec_env,
_va_list va_args) 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint8 *native_end_offset; uint8 *native_end_offset;
struct str_context ctx; struct str_context ctx;
/* str and format have been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)str, 1))
if (!validate_native_addr(va_args, sizeof(uint32)))
return 0; 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)) { &native_end_offset)) {
wasm_runtime_set_exception(module_inst, "out of bounds memory access"); wasm_runtime_set_exception(module_inst, "out of bounds memory access");
return false; return false;
} }
ctx.str = str; ctx.str = native_str;
ctx.max = (uint32)(native_end_offset - (uint8 *)str); ctx.max = (uint32)(native_end_offset - (uint8 *)native_str);
ctx.count = 0; 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)) module_inst))
return 0; return 0;
if (ctx.count < ctx.max) { if (ctx.count < ctx.max) {
str[ctx.count] = '\0'; native_str[ctx.count] = '\0';
} }
return (int)ctx.count; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
struct str_context ctx; struct str_context ctx;
/* str and format have been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)str, size))
if (!validate_native_addr(va_args, sizeof(uint32)))
return 0; 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.max = size;
ctx.count = 0; 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)) module_inst))
return 0; return 0;
if (ctx.count < ctx.max) { if (ctx.count < ctx.max) {
str[ctx.count] = '\0'; native_str[ctx.count] = '\0';
} }
return (int)ctx.count; return (int)ctx.count;
@ -540,7 +576,13 @@ snprintf_wrapper(wasm_exec_env_t exec_env, char *str, uint32 size,
static int static int
puts_wrapper(wasm_exec_env_t exec_env, const char *str) 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 static int
@ -553,18 +595,23 @@ putchar_wrapper(wasm_exec_env_t exec_env, int c)
static uint32 static uint32
strdup_wrapper(wasm_exec_env_t exec_env, const char *str) strdup_wrapper(wasm_exec_env_t exec_env, const char *str)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
char *str_ret; char *str_ret = 0;
uint32 len; uint32 len;
uint32 str_ret_offset = 0; 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 */ /* str has been checked by runtime */
if (str) { if (native_str) {
len = (uint32)strlen(str) + 1; len = (uint32)strlen(native_str) + 1;
str_ret_offset = module_malloc(len, (void **)&str_ret); str_ret_offset = module_malloc(len, (void **)&str_ret);
if (str_ret_offset) { 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* s2 has been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)s1, size))
if (!validate_native_addr((void *)s1, size))
return 0; 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 static uint32
@ -595,47 +647,55 @@ memcpy_wrapper(wasm_exec_env_t exec_env, void *dst, const void *src,
uint32 size) uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst);
if (size == 0) if (size == 0)
return dst_offset; return (uint32)(uintptr_t)dst;
/* src has been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)src, size))
if (!validate_native_addr(dst, size)) return (uint32)(uintptr_t)dst;
return dst_offset;
bh_memcpy_s(dst, size, src, size); if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return dst_offset; 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 static uint32
memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size) memmove_wrapper(wasm_exec_env_t exec_env, void *dst, void *src, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 dst_offset = addr_native_to_app(dst);
if (size == 0) if (size == 0)
return dst_offset; return (uint32)(uintptr_t)dst;
/* src has been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)src, size))
if (!validate_native_addr(dst, size)) return (uint32)(uintptr_t)dst;
return dst_offset;
memmove(dst, src, size); if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return dst_offset; 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 static uint32
memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size) memset_wrapper(wasm_exec_env_t exec_env, void *s, int32 c, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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)) if (!validate_app_addr((uint32)(uintptr_t)s, size))
return s_offset; return (uint32)(uintptr_t)s;
memset(s, c, size); void * native_s = addr_app_to_native((uint32)(uintptr_t)s);
return s_offset;
memset(native_s, c, size);
return (uint32)(uintptr_t)s;
} }
static uint32 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *ret; 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 */ /* s has been checked by runtime */
ret = strchr(s, c); ret = strchr(native_s, c);
return ret ? addr_native_to_app(ret) : 0; return ret ? addr_native_to_app(ret) : 0;
} }
static int32 static int32
strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2) strcmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2)
{ {
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 */ /* s1 and s2 have been checked by runtime */
return strcmp(s1, s2); return strcmp(native_s1, native_s2);
} }
static int32 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* s2 has been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)s1, size))
if (!validate_native_addr((void *)s1, size))
return 0; 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 static uint32
strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src) strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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_app_str_addr((uint32)(uintptr_t)src))
if (!validate_native_addr(dst, len))
return 0; 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 #ifndef BH_PLATFORM_WINDOWS
strncpy(dst, src, len); strncpy(native_dst, native_src, len);
#else #else
strncpy_s(dst, len, src, len); strncpy_s(native_dst, len, native_src, len);
#endif #endif
return addr_native_to_app(dst); return (uint32)(uintptr_t)dst;
} }
static uint32 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
/* src has been checked by runtime */ if (!validate_app_addr((uint32)(uintptr_t)src, size))
if (!validate_native_addr(dst, size))
return 0; 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 #ifndef BH_PLATFORM_WINDOWS
strncpy(dst, src, size); strncpy(native_dst, native_src, size);
#else #else
strncpy_s(dst, size, src, size); strncpy_s(native_dst, size, native_src, size);
#endif #endif
return addr_native_to_app(dst); return (uint32)(uintptr_t)dst;
} }
static uint32 static uint32
strlen_wrapper(wasm_exec_env_t exec_env, const char *s) 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 */ /* s has been checked by runtime */
return (uint32)strlen(s); return (uint32)strlen(native_str);
} }
static uint32 static uint32
malloc_wrapper(wasm_exec_env_t exec_env, uint32 size) 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); return module_malloc(size, NULL);
} }
static uint32 static uint32
calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size) 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; uint64 total_size = (uint64)nmemb * (uint64)size;
uint32 ret_offset = 0; uint32 ret_offset = 0;
uint8 *ret_ptr; uint8 *ret_ptr;
@ -741,7 +840,7 @@ calloc_wrapper(wasm_exec_env_t exec_env, uint32 nmemb, uint32 size)
static uint32 static uint32
realloc_wrapper(wasm_exec_env_t exec_env, uint32 ptr, uint32 new_size) 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); 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 static void
free_wrapper(wasm_exec_env_t exec_env, void *ptr) 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; return;
module_free(addr_native_to_app(ptr)); module_free((uint32)(uintptr_t)ptr);
} }
static int32 static int32
atoi_wrapper(wasm_exec_env_t exec_env, const char *s) 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 */ /* s has been checked by runtime */
return atoi(s); return atoi(native_s);
} }
static void 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
int32 num = 0; int32 num = 0;
/* nptr has been checked by runtime */ if (!validate_app_str_addr((uint32)(uintptr_t)nptr))
if (!validate_native_addr(endptr, sizeof(uint32)))
return 0; return 0;
num = (int32)strtol(nptr, endptr, base); /* nptr has been checked by runtime */
*(uint32 *)endptr = addr_native_to_app(*endptr); 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; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 num = 0; uint32 num = 0;
/* nptr has been checked by runtime */ if (!validate_app_str_addr((uint32)(uintptr_t)nptr))
if (!validate_native_addr(endptr, sizeof(uint32)))
return 0; return 0;
num = (uint32)strtoul(nptr, endptr, base); /* nptr has been checked by runtime */
*(uint32 *)endptr = addr_native_to_app(*endptr); 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; 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 static uint32
memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n) memchr_wrapper(wasm_exec_env_t exec_env, const void *s, int32 c, uint32 n)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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; 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); 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, strncasecmp_wrapper(wasm_exec_env_t exec_env, const char *s1, const char *s2,
uint32 n) 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 */ /* s1 and s2 have been checked by runtime */
return strncasecmp(s1, s2, n); return strncasecmp(native_s1, native_s2, n);
} }
static uint32 static uint32
strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept) strspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *accept)
{ {
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 */ /* s and accept have been checked by runtime */
return (uint32)strspn(s, accept); return (uint32)strspn(native_s, native_accept);
} }
static uint32 static uint32
strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject) strcspn_wrapper(wasm_exec_env_t exec_env, const char *s, const char *reject)
{ {
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 */ /* s and reject have been checked by runtime */
return (uint32)strcspn(s, reject); return (uint32)strcspn(native_s, native_reject);
} }
static uint32 static uint32
strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find) strstr_wrapper(wasm_exec_env_t exec_env, const char *s, const char *find)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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 */ /* 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); return addr_native_to_app(res);
} }
@ -884,7 +1067,8 @@ isprint_wrapper(wasm_exec_env_t exec_env, int32 c)
static int32 static int32
isdigit_wrapper(wasm_exec_env_t exec_env, int32 c) isdigit_wrapper(wasm_exec_env_t exec_env, int32 c)
{ {
return isdigit(c); return c;
//return isdigit(c);
} }
static int32 static int32
@ -905,6 +1089,37 @@ toupper_wrapper(wasm_exec_env_t exec_env, int32 c)
return toupper(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 static int32
isalnum_wrapper(wasm_exec_env_t exec_env, int32 c) 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) const void *src, uint32 size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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_app_addr((uint32)(uintptr_t)src, size))
if (!validate_native_addr(dst, size)) return 0;
return dst_offset;
bh_memcpy_s(dst, size, src, size); if (!validate_app_addr((uint32)(uintptr_t)dst, size))
return dst_offset; 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 static void
abort_wrapper(wasm_exec_env_t exec_env, int32 code) abort_wrapper(wasm_exec_env_t exec_env, int32 code)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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); snprintf(buf, sizeof(buf), "env.abort(%i)", code);
wasm_runtime_set_exception(module_inst, buf); wasm_runtime_set_exception(module_inst, buf);
} }
@ -1020,7 +1258,7 @@ static void
abortStackOverflow_wrapper(wasm_exec_env_t exec_env, int32 code) abortStackOverflow_wrapper(wasm_exec_env_t exec_env, int32 code)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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); snprintf(buf, sizeof(buf), "env.abortStackOverflow(%i)", code);
wasm_runtime_set_exception(module_inst, buf); wasm_runtime_set_exception(module_inst, buf);
} }
@ -1029,7 +1267,7 @@ static void
nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code) nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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); snprintf(buf, sizeof(buf), "env.nullFunc_X(%i)", code);
wasm_runtime_set_exception(module_inst, buf); wasm_runtime_set_exception(module_inst, buf);
} }
@ -1037,7 +1275,7 @@ nullFunc_X_wrapper(wasm_exec_env_t exec_env, int32 code)
static uint32 static uint32
__cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size) __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, uint32 thrown_size)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_root_module_inst(exec_env);
uint32 exception = module_malloc(thrown_size, NULL); uint32 exception = module_malloc(thrown_size, NULL);
if (!exception) if (!exception)
return 0; return 0;
@ -1054,7 +1292,7 @@ __cxa_throw_wrapper(wasm_exec_env_t exec_env, void *thrown_exception,
void *tinfo, uint32 table_elem_idx) void *tinfo, uint32 table_elem_idx)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); 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++"); snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
wasm_runtime_set_exception(module_inst, buf); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint64 time; 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; return (uint32)-1;
struct timespec_app * native_ts_app = addr_app_to_native((uint32)(uintptr_t)ts_app);
time = os_time_get_boot_microsecond(); time = os_time_get_boot_microsecond();
ts_app->tv_sec = time / 1000000; native_ts_app->tv_sec = time / 1000000;
ts_app->tv_nsec = (time % 1000000) * 1000; native_ts_app->tv_nsec = (time % 1000000) * 1000;
return (uint32)0; return (uint32)0;
} }
@ -1090,6 +1330,57 @@ clock_wrapper(wasm_exec_env_t exec_env)
return os_time_get_boot_microsecond() * 1000; 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 #if WASM_ENABLE_SPEC_TEST != 0
static void static void
print_wrapper(wasm_exec_env_t exec_env) 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 */ /* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #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 */ /* clang-format on */
static NativeSymbol native_symbols_libc_builtin[] = { static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(iprintf, "($*)i"),
REG_NATIVE_FUNC(printf, "($*)i"), REG_NATIVE_FUNC(printf, "($*)i"),
REG_NATIVE_FUNC(sprintf, "($$*)i"), REG_NATIVE_FUNC(sprintf, "($$*)i"),
REG_NATIVE_FUNC(snprintf, "(*~$*)i"), REG_NATIVE_FUNC(snprintf, "(*~$*)i"),
@ -1160,6 +1455,7 @@ static NativeSymbol native_symbols_libc_builtin[] = {
REG_NATIVE_FUNC(exit, "(i)"), REG_NATIVE_FUNC(exit, "(i)"),
REG_NATIVE_FUNC(strtol, "($*i)i"), REG_NATIVE_FUNC(strtol, "($*i)i"),
REG_NATIVE_FUNC(strtoul, "($*i)i"), REG_NATIVE_FUNC(strtoul, "($*i)i"),
REG_NATIVE_FUNC(strtod, "($*)F"),
REG_NATIVE_FUNC(memchr, "(*ii)i"), REG_NATIVE_FUNC(memchr, "(*ii)i"),
REG_NATIVE_FUNC(strncasecmp, "($$i)"), REG_NATIVE_FUNC(strncasecmp, "($$i)"),
REG_NATIVE_FUNC(strspn, "($$)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(isxdigit, "(i)i"),
REG_NATIVE_FUNC(tolower, "(i)i"), REG_NATIVE_FUNC(tolower, "(i)i"),
REG_NATIVE_FUNC(toupper, "(i)i"), REG_NATIVE_FUNC(toupper, "(i)i"),
REG_NATIVE_FUNC(__ctype_tolower_loc, "()i"),
REG_NATIVE_FUNC(isalnum, "(i)i"), REG_NATIVE_FUNC(isalnum, "(i)i"),
REG_NATIVE_FUNC(setTempRet0, "(i)"), REG_NATIVE_FUNC(setTempRet0, "(i)"),
REG_NATIVE_FUNC(getTempRet0, "()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(llvm_stacksave, "()i"),
REG_NATIVE_FUNC(emscripten_memcpy_big, "(**~)i"), REG_NATIVE_FUNC(emscripten_memcpy_big, "(**~)i"),
REG_NATIVE_FUNC(abort, "(i)"), REG_NATIVE_FUNC(abort, "(i)"),
REG_AS_NATIVE_FUNC(abort, "($$ii)"),
REG_NATIVE_FUNC(abortStackOverflow, "(i)"), REG_NATIVE_FUNC(abortStackOverflow, "(i)"),
REG_NATIVE_FUNC(nullFunc_X, "(i)"), REG_NATIVE_FUNC(nullFunc_X, "(i)"),
REG_NATIVE_FUNC(__cxa_allocate_exception, "(i)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(__cxa_throw, "(**i)"),
REG_NATIVE_FUNC(clock_gettime, "(i*)i"), REG_NATIVE_FUNC(clock_gettime, "(i*)i"),
REG_NATIVE_FUNC(clock, "()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 #if WASM_ENABLE_SPEC_TEST != 0

View File

@ -15,6 +15,9 @@
#define get_module_inst(exec_env) \ #define get_module_inst(exec_env) \
wasm_runtime_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) \ #define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, 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, mmap_wrapper(wasm_exec_env_t exec_env, void *addr, int length, int prot,
int flags, int fd, int64 offset) 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; uint32 buf_offset;
char *buf; char *buf;
int size_read; int size_read;

View File

@ -1076,7 +1076,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
/* clang-format off */ /* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #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 */ /* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = { static NativeSymbol native_symbols_libc_wasi[] = {

View File

@ -5,6 +5,7 @@
#include "libc_wasi_wrapper.h" #include "libc_wasi_wrapper.h"
#include "bh_platform.h" #include "bh_platform.h"
#include "ConstStrDesc.h"
#include "wasm_export.h" #include "wasm_export.h"
void 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); total_size = sizeof(int32) * ((uint64)argc + 1);
if (total_size >= UINT32_MAX 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(char *) * ((uint64)argc + 1); total_size = sizeof(char *) * ((uint64)argc + 1);
if (total_size >= UINT32_MAX if (total_size >= UINT32_MAX
|| !(argv = wasm_runtime_malloc((uint32)total_size))) || !(argv = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1; 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) { if (err) {
wasm_runtime_free(argv); wasm_runtime_free(argv);
return err; return err;
} }
uint32 * native_argv_offsets = addr_app_to_native((uint32)(intptr_t)argv_offsets);
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
argv_offsets[i] = addr_native_to_app(argv[i]); native_argv_offsets[i] = addr_native_to_app(argv[i]);
argv_offsets[argc] = 0; native_argv_offsets[argc] = 0;
wasm_runtime_free(argv); wasm_runtime_free(argv);
return 0; return 0;
@ -141,8 +147,8 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
if (!validate_native_addr(argc_app, sizeof(uint32)) if (!validate_app_addr((uint32)(intptr_t)argc_app, sizeof(uint32))
|| !validate_native_addr(argv_buf_size_app, sizeof(uint32))) || !validate_app_addr((uint32)(intptr_t)argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
argv_environ = wasi_ctx->argv_environ; 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) if (err)
return err; return err;
*argc_app = (uint32)argc; uint32 * native_argc_app = addr_app_to_native((uint32)(intptr_t)argc_app);
*argv_buf_size_app = (uint32)argv_buf_size; 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; 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); 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 (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 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); 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 (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 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); total_size = sizeof(int32) * ((uint64)environ_count + 1);
if (total_size >= UINT32_MAX 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(char *) * (((uint64)environ_count + 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))) || !(environs = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1; 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) { if (err) {
wasm_runtime_free(environs); wasm_runtime_free(environs);
return err; return err;
} }
char * native_environ_offsets = addr_app_to_native((uint32)(intptr_t)environ_offsets);
for (i = 0; i < environ_count; i++) for (i = 0; i < environ_count; i++)
environ_offsets[i] = addr_native_to_app(environs[i]); native_environ_offsets[i] = addr_native_to_app(environs[i]);
environ_offsets[environ_count] = 0; native_environ_offsets[environ_count] = 0;
wasm_runtime_free(environs); wasm_runtime_free(environs);
return 0; return 0;
@ -245,8 +260,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
if (!validate_native_addr(environ_count_app, sizeof(uint32)) if (!validate_app_addr((uint32)(intptr_t)environ_count_app, sizeof(uint32))
|| !validate_native_addr(environ_buf_size_app, sizeof(uint32))) || !validate_app_addr((uint32)(intptr_t)environ_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count, 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) if (err)
return err; return err;
*environ_count_app = (uint32)environ_count; uint32 * native_environ_count_app = addr_app_to_native((uint32)(intptr_t)environ_count_app);
*environ_buf_size_app = (uint32)environ_buf_size; 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; return 0;
} }
@ -273,15 +291,17 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; 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; return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_prestat_get(prestats, fd, &prestat); err = wasmtime_ssp_fd_prestat_get(prestats, fd, &prestat);
if (err) if (err)
return err; return err;
prestat_app->pr_type = prestat.pr_type; wasi_prestat_app_t * native_prestat_app = addr_app_to_native((uint32)(intptr_t)prestat_app);
prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
native_prestat_app->pr_type = prestat.pr_type;
native_prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
return 0; 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 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; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len; 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; iovec = iovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) { iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(native_iovec_app->buf_offset);
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = native_iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset, 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) if (err)
goto fail; 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 */ /* success */
err = 0; err = 0;
@ -397,9 +426,9 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; 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; ciovec = ciovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) { iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(native_iovec_app->buf_offset);
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = native_iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset, 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) if (err)
goto fail; 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 */ /* success */
err = 0; err = 0;
@ -450,9 +482,9 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len; 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; iovec = iovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) { iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(intptr_t)iovec_app);
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset); iovec->buf = (void *)addr_app_to_native(native_iovec_app->buf_offset);
iovec->buf_len = iovec_app->buf_len; iovec->buf_len = native_iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread); err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread);
if (err) if (err)
goto fail; 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 */ /* success */
err = 0; 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 (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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 (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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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; return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat); err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat);
if (err) if (err)
return 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; return 0;
} }
@ -617,9 +657,13 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)iovs_len; total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32)) if (total_size >= UINT32_MAX)
|| total_size >= UINT32_MAX return (wasi_errno_t)-1;
|| !validate_native_addr((void *)iovec_app, (uint32)total_size))
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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len; 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; ciovec = ciovec_begin;
for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) { iovec_app_t * native_iovec_app = addr_app_to_native((uint32)(uintptr_t)iovec_app);
if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) { 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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset); ciovec->buf = (char *)addr_app_to_native(native_iovec_app->buf_offset);
ciovec->buf_len = iovec_app->buf_len; ciovec->buf_len = native_iovec_app->buf_len;
} }
err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten); err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten);
if (err) if (err)
goto fail; goto fail;
*nwritten_app = (uint32)nwritten; *native_nwritten_app = (uint32)nwritten;
/* success */ /* success */
err = 0; err = 0;
@ -691,7 +738,12 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path, if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
old_path_len, new_fd, new_path, new_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 static wasi_errno_t
@ -728,14 +789,20 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; 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; 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, oflags, fs_rights_base, fs_rights_inheriting,
fs_flags, &fd); 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; return err;
} }
@ -752,14 +819,21 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; 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; 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) if (err)
return 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; 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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; 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); &bufused);
if (err) if (err)
return 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; return 0;
} }
@ -801,8 +886,17 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len, if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
new_fd, new_path, new_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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 (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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len, if (!validate_app_addr((uint32)(uintptr_t)filestat, sizeof(wasi_filestat_t)))
filestat); 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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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( 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 static wasi_errno_t
@ -901,8 +1008,17 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
if (!wasi_ctx) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len, if (!validate_app_addr((uint32)(uintptr_t)old_path, old_path_len))
fd, new_path, new_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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; 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 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) if (!wasi_ctx)
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
if (!validate_native_addr((void *)in, sizeof(wasi_subscription_t)) if (!validate_app_addr((uint32)(uintptr_t)in, sizeof(wasi_subscription_t))
|| !validate_native_addr(out, sizeof(wasi_event_t)) || !validate_app_addr((uint32)(uintptr_t)out, sizeof(wasi_event_t))
|| !validate_native_addr(nevents_app, sizeof(uint32))) || !validate_app_addr((uint32)(uintptr_t)nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1; 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) if (err)
return 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; return 0;
} }
@ -983,7 +1113,12 @@ wasi_proc_raise(wasm_exec_env_t exec_env, wasi_signal_t sig)
static wasi_errno_t static wasi_errno_t
wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len) 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 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; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)ri_data_len; total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
if (!validate_native_addr(ro_datalen_app, (uint32)sizeof(uint32)) if (!validate_app_addr((uint32)(uintptr_t)ro_datalen_app, (uint32)sizeof(uint32))
|| !validate_native_addr(ro_flags, (uint32)sizeof(wasi_roflags_t)) || !validate_app_addr((uint32)(uintptr_t)ro_flags, (uint32)sizeof(wasi_roflags_t))
|| total_size >= UINT32_MAX || 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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)ri_data_len; 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; iovec = iovec_begin;
for (i = 0; i < ri_data_len; i++, ri_data++, iovec++) { iovec_app_t * native_ri_data = addr_app_to_native((uint32)(uintptr_t)ri_data);
if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) { 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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset); iovec->buf = (void *)addr_app_to_native(native_ri_data->buf_offset);
iovec->buf_len = ri_data->buf_len; 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, 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) if (err)
goto fail; 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 */ /* success */
err = 0; err = 0;
@ -1059,9 +1198,9 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
total_size = sizeof(iovec_app_t) * (uint64)si_data_len; 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 || 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; return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len; 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; ciovec = ciovec_begin;
for (i = 0; i < si_data_len; i++, si_data++, ciovec++) { iovec_app_t * native_si_data = addr_app_to_native((uint32)(uintptr_t)si_data);
if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
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; err = (wasi_errno_t)-1;
goto fail; goto fail;
} }
ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset); ciovec->buf = (char *)addr_app_to_native(native_si_data->buf_offset);
ciovec->buf_len = si_data->buf_len; ciovec->buf_len = native_si_data->buf_len;
} }
err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len, err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len,
@ -1085,7 +1226,9 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
if (err) if (err)
goto fail; 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 */ /* success */
err = 0; err = 0;
@ -1116,7 +1259,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
/* clang-format off */ /* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \ #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 */ /* clang-format on */
static NativeSymbol native_symbols_libc_wasi[] = { 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; 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 bool
bh_hash_map_insert(HashMap *map, void *key, void *value) 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 bool
bh_hash_map_insert(HashMap *map, void *key, void *value); 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 * 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; *ret_size = file_size;
printf("Read file %s to buffer successfully\n", filename);
return buffer; return buffer;
} }
#else /* else of defined(_WIN32) || defined(_WIN32_) */ #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; *ret_size = file_size;
printf("Read file %s to buffer successfully\n", filename);
return buffer; return buffer;
} }
#endif /* end of defined(_WIN32) || defined(_WIN32_) */ #endif /* end of defined(_WIN32) || defined(_WIN32_) */

View File

@ -4,6 +4,7 @@
cmake_minimum_required (VERSION 2.8) cmake_minimum_required (VERSION 2.8)
project (iwasm) project (iwasm)
# set (CMAKE_VERBOSE_MAKEFILE 1) # set (CMAKE_VERBOSE_MAKEFILE 1)
set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_PLATFORM "linux")
@ -55,6 +56,10 @@ if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
set (WAMR_BUILD_LIBC_BUILTIN 1) set (WAMR_BUILD_LIBC_BUILTIN 1)
endif () endif ()
if (NOT DEFINED AS_HARDCODE_ABORT)
set (AS_HARDCODE_ABORT 0)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_WASI) if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
# Enable libc wasi support by default # Enable libc wasi support by default
set (WAMR_BUILD_LIBC_WASI 1) set (WAMR_BUILD_LIBC_WASI 1)
@ -70,6 +75,17 @@ if (NOT DEFINED WAMR_BUILD_MULTI_MODULE)
set (WAMR_BUILD_MULTI_MODULE 0) set (WAMR_BUILD_MULTI_MODULE 0)
endif () 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) if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
# Disable pthread library by default # Disable pthread library by default
set (WAMR_BUILD_LIB_PTHREAD 0) set (WAMR_BUILD_LIB_PTHREAD 0)

View File

@ -3,4 +3,4 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/ */
#include "../posix/main.c" #include "../posix/main.c"

View File

@ -19,6 +19,16 @@ static char **app_argv;
#define MODULE_PATH ("--module-path=") #define MODULE_PATH ("--module-path=")
/* clang-format off */ /* 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 static int
print_help() print_help()
{ {
@ -36,6 +46,18 @@ print_help()
" that runs commands in the form of \"FUNC ARG...\"\n"); " that runs commands in the form of \"FUNC ARG...\"\n");
printf(" --xip Enable XIP (Execution In Place) mode to run AOT file\n" printf(" --xip Enable XIP (Execution In Place) mode to run AOT file\n"
" generated with \"--enable-indirect-mode\" flag\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 #if WASM_ENABLE_LIBC_WASI != 0
printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n"); printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
printf(" to the program, for example:\n"); printf(" to the program, for example:\n");
@ -44,7 +66,7 @@ print_help()
printf(" to the program, for example:\n"); printf(" to the program, for example:\n");
printf(" --dir=<dir1> --dir=<dir2>\n"); printf(" --dir=<dir1> --dir=<dir2>\n");
#endif #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" printf(" --module-path= Indicate a module search path. default is current\n"
" directory('./')\n"); " directory('./')\n");
#endif #endif
@ -57,8 +79,36 @@ print_help()
#endif #endif
return 1; 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 * static void *
app_instance_main(wasm_module_inst_t module_inst) app_instance_main(wasm_module_inst_t module_inst)
{ {
@ -120,6 +170,44 @@ split_string(char *str, int *count)
} }
return res; 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 * static void *
app_instance_repl(wasm_module_inst_t module_inst) app_instance_repl(wasm_module_inst_t module_inst)
@ -182,7 +270,7 @@ static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif #endif
#endif #endif
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0 || WASM_ENABLE_DYNAMIC_LINKING != 0
static char * static char *
handle_module_path(const char *module_path) handle_module_path(const char *module_path)
{ {
@ -190,30 +278,77 @@ handle_module_path(const char *module_path)
return (strchr(module_path, '=')) + 1; return (strchr(module_path, '=')) + 1;
} }
static char *module_search_path = "."; static char * module_search_paths = NULL;
static bool static bool
module_reader_callback(const char *module_name, uint8 **p_buffer, module_reader_callback(const char *module_name, uint8 **p_buffer,
uint32 *p_size) uint32 *p_size)
{ {
const char *format = "%s/%s.wasm"; #if WASM_ENABLE_DYNAMIC_LINKING != 0
int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) const char * format = "/%s";
+ strlen(".wasm") + 1; const char * format_with_path = "%s/%s";
char *wasm_file_name = BH_MALLOC(sz); #else
if (!wasm_file_name) { 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; 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); if (*p_buffer)
return *p_buffer != NULL; 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 static void
moudle_destroyer(uint8 *buffer, uint32 size) module_destroyer_impl(uint8 *buffer, uint32 size)
{ {
if (!buffer) { if (!buffer) {
return; return;
@ -228,6 +363,7 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *wasm_file = NULL; char *wasm_file = NULL;
const char * file_name = NULL;
const char *func_name = NULL; const char *func_name = NULL;
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
uint32 wasm_file_size; uint32 wasm_file_size;
@ -240,7 +376,12 @@ main(int argc, char *argv[])
int log_verbose_level = 2; int log_verbose_level = 2;
#endif #endif
bool is_repl_mode = false; bool is_repl_mode = false;
bool is_xip_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 #if WASM_ENABLE_LIBC_WASI != 0
const char *dir_list[8] = { NULL }; const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0; uint32 dir_list_size = 0;
@ -273,9 +414,20 @@ main(int argc, char *argv[])
else if (!strcmp(argv[0], "--repl")) { else if (!strcmp(argv[0], "--repl")) {
is_repl_mode = true; is_repl_mode = true;
} }
else if (!strcmp(argv[0], "--xip")) { else if (!strcmp(argv[0], "--xip")) {
is_xip_mode = true; 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)) { else if (!strncmp(argv[0], "--stack-size=", 13)) {
if (argv[0][13] == '\0') if (argv[0][13] == '\0')
return print_help(); return print_help();
@ -318,10 +470,10 @@ main(int argc, char *argv[])
} }
} }
#endif /* WASM_ENABLE_LIBC_WASI */ #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))) { else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
module_search_path = handle_module_path(argv[0]); module_search_paths = handle_module_path(argv[0]);
if (!strlen(module_search_path)) { if (!strlen(module_search_paths)) {
return print_help(); return print_help();
} }
} }
@ -358,6 +510,8 @@ main(int argc, char *argv[])
app_argv = argv; app_argv = argv;
memset(&init_args, 0, sizeof(RuntimeInitArgs)); 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 #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
init_args.mem_alloc_type = Alloc_With_Pool; init_args.mem_alloc_type = Alloc_With_Pool;
@ -377,6 +531,23 @@ main(int argc, char *argv[])
strcpy(init_args.ip_addr, ip_addr); strcpy(init_args.ip_addr, ip_addr);
#endif #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 */ /* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) { if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime environment failed.\n"); printf("Init runtime environment failed.\n");
@ -411,15 +582,50 @@ main(int argc, char *argv[])
} }
#if WASM_ENABLE_MULTI_MODULE != 0 #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 #endif
file_name = strrchr(wasm_file, '/');
if (file_name)
file_name ++;
else
file_name = wasm_file;
/* load WASM module */ /* 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)))) { error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf); printf("%s\n", error_buf);
goto fail2; 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 #if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 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: fail3:
/* unload the module */ /* unload the module */
wasm_runtime_unload(wasm_module); wasm_runtime_unload2(wasm_module);
fail2: fail2:
/* free the file buffer */ /* free the file buffer */

View File

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

View File

@ -53,8 +53,8 @@ function run_case_w_aot() {
--aot --aot-target ${TARGET} \ --aot --aot-target ${TARGET} \
${SGX_OPT} \ ${SGX_OPT} \
${SIMD_OPT} \ ${SIMD_OPT} \
${REF_TYPES_OPT} ${REF_TYPES_OPT} \
#--no_cleanup --no_cleanup
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
echo "============> run ${test_case} failed" echo "============> run ${test_case} failed"
exit 1 exit 1
@ -71,8 +71,8 @@ function run_case_wo_aot() {
--aot-compiler ${WAMRC_CMD} \ --aot-compiler ${WAMRC_CMD} \
${SGX_OPT} \ ${SGX_OPT} \
${SIMD_OPT} \ ${SIMD_OPT} \
${REF_TYPES_OPT} ${REF_TYPES_OPT} \
#--no_cleanup --no_cleanup
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
echo "============> run ${test_case} failed" echo "============> run ${test_case} failed"
exit 1 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', parser.add_argument('--multi-thread', default=False, action='store_true',
help="Enable Multi-thread") 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', parser.add_argument('--verbose', default=False, action='store_true',
help='show more logs') help='show more logs')
@ -965,15 +968,27 @@ def run_wasm_with_repl(wasm_tempfile, aot_tempfile, opts, r):
if not test_aot: if not test_aot:
log("Starting interpreter for module '%s'" % wasm_tempfile) log("Starting interpreter for module '%s'" % wasm_tempfile)
if opts.verbose: if opts.verbose:
cmd = [opts.interpreter, "--heap-size=0", "-v=5", "--repl", wasm_tempfile] 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: else:
cmd = [opts.interpreter, "--heap-size=0", "--repl", wasm_tempfile] 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: else:
log("Starting aot for module '%s'" % aot_tempfile) log("Starting aot for module '%s'" % aot_tempfile)
if opts.verbose: if opts.verbose:
cmd = [opts.interpreter, "--heap-size=0", "-v=5", "--repl", aot_tempfile] 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: else:
cmd = [opts.interpreter, "--heap-size=0", "--repl", aot_tempfile] 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]
log("Running: %s" % " ".join(cmd)) log("Running: %s" % " ".join(cmd))
if (r != None): if (r != None):

View File

@ -20,6 +20,7 @@ function help()
echo "-M enable the multi module feature" echo "-M enable the multi module feature"
echo "-p enable multi thread feature" echo "-p enable multi thread feature"
echo "-S enable SIMD" echo "-S enable SIMD"
echo "-d enable dynamic linking"
echo "-x test SGX" echo "-x test SGX"
echo "-b use the wabt binary release package instead of compiling from the source code" echo "-b use the wabt binary release package instead of compiling from the source code"
echo "-P run the spec test parallelly" echo "-P run the spec test parallelly"
@ -32,6 +33,8 @@ TYPE=("classic-interp" "fast-interp" "jit" "aot")
#default target #default target
TARGET="X86_64" TARGET="X86_64"
ENABLE_MULTI_MODULE=0 ENABLE_MULTI_MODULE=0
ENABLE_DYNAMIC_LINKING=0
ENABLE_DLOPEN=0
ENABLE_MULTI_THREAD=0 ENABLE_MULTI_THREAD=0
COLLECT_CODE_COVERAGE=0 COLLECT_CODE_COVERAGE=0
ENABLE_SIMD=0 ENABLE_SIMD=0
@ -41,7 +44,7 @@ SGX_OPT=""
PLATFORM=$(uname -s | tr A-Z a-z) PLATFORM=$(uname -s | tr A-Z a-z)
PARALLELISM=0 PARALLELISM=0
while getopts ":s:cabt:m:MCpSxP" opt while getopts ":s:cabt:m:MdDCpSxP" opt
do do
OPT_PARSED="TRUE" OPT_PARSED="TRUE"
case $opt in case $opt in
@ -94,6 +97,15 @@ do
echo "enable multi module feature" echo "enable multi module feature"
ENABLE_MULTI_MODULE=1 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) C)
echo "enable code coverage" echo "enable code coverage"
COLLECT_CODE_COVERAGE=1 COLLECT_CODE_COVERAGE=1
@ -156,6 +168,7 @@ readonly CLASSIC_INTERP_COMPILE_FLAGS="\
-DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=0 \ -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=0 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \ -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \
-DWAMR_BUILD_SPEC_TEST=1 \ -DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}" -DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
readonly FAST_INTERP_COMPILE_FLAGS="\ 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_INTERP=1 -DWAMR_BUILD_FAST_INTERP=1 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \ -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=0 \
-DWAMR_BUILD_SPEC_TEST=1 \ -DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}" -DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
# jit: report linking error if set 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_INTERP=0 -DWAMR_BUILD_FAST_INTERP=0 \
-DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=1 \ -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=1 \
-DWAMR_BUILD_SPEC_TEST=1 \ -DWAMR_BUILD_SPEC_TEST=1 \
-DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING} \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}" -DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE}"
readonly COMPILE_FLAGS=( readonly COMPILE_FLAGS=(
@ -265,16 +280,16 @@ function spec_test()
pushd spec pushd spec
# restore and clean everything # restore and clean everything
git reset --hard HEAD #git reset --hard HEAD
# update basic test cases # update basic test cases
echo "update spec test cases" echo "update spec test cases"
git fetch origin master #git fetch origin master
# restore from XX_ignore_cases.patch # restore from XX_ignore_cases.patch
# resotre branch # resotre branch
git checkout -B master #git checkout -B master
git reset --hard 397399a70565609bf142d211891724e21bffd01f #git reset --hard 397399a70565609bf142d211891724e21bffd01f
git apply ../../spec-test-script/ignore_cases.patch #git apply ../../spec-test-script/ignore_cases.patch
# udpate thread cases # udpate thread cases
if [ ${ENABLE_MULTI_THREAD} == 1 ]; then 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/all.py .
ln -sf ${WORK_DIR}/../spec-test-script/runtest.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 # multi-module only enable in interp mode
if [[ 1 == ${ENABLE_MULTI_MODULE} ]]; then if [[ 1 == ${ENABLE_MULTI_MODULE} ]]; then
@ -386,6 +401,10 @@ function spec_test()
ARGS_FOR_SPEC_TEST+="-t -m ${TARGET} " ARGS_FOR_SPEC_TEST+="-t -m ${TARGET} "
fi fi
if [[ 1 == ${ENABLE_DLOPEN} ]]; then
ARGS_FOR_SPEC_TEST+="-D "
fi
if [[ ${PARALLELISM} == 1 ]]; then if [[ ${PARALLELISM} == 1 ]]; then
ARGS_FOR_SPEC_TEST+="--parl " ARGS_FOR_SPEC_TEST+="--parl "
fi fi
@ -474,7 +493,7 @@ function build_iwasm_with_cfg()
&& if [ -d build ]; then rm -rf build/*; else mkdir build; fi \ && if [ -d build ]; then rm -rf build/*; else mkdir build; fi \
&& cd build \ && cd build \
&& cmake $* .. \ && cmake $* .. \
&& make -j 4 && make -j 12
fi fi
if [ "$?" != 0 ];then if [ "$?" != 0 ];then
@ -497,8 +516,8 @@ function build_wamrc()
&& ./build_llvm.sh \ && ./build_llvm.sh \
&& if [ -d build ]; then rm -r build/*; else mkdir build; fi \ && if [ -d build ]; then rm -r build/*; else mkdir build; fi \
&& cd build \ && cd build \
&& cmake .. \ && cmake .. -DWAMR_BUILD_DYNAMIC_LINKING=${ENABLE_DYNAMIC_LINKING}\
&& make -j 4 && make -j 12
} }
### Need to add a test suite? ### 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_DUMP_CALL_STACK=1)
add_definitions(-DWASM_ENABLE_PERF_PROFILING=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: # Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32" # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
if (NOT WAMR_BUILD_TARGET) if (NOT WAMR_BUILD_TARGET)
@ -66,20 +74,24 @@ elseif (WAMR_BUILD_TARGET STREQUAL "AMD_64")
add_definitions(-DBUILD_TARGET_AMD_64) add_definitions(-DBUILD_TARGET_AMD_64)
elseif (WAMR_BUILD_TARGET STREQUAL "X86_32") elseif (WAMR_BUILD_TARGET STREQUAL "X86_32")
add_definitions(-DBUILD_TARGET_X86_32) add_definitions(-DBUILD_TARGET_X86_32)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*") elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
add_definitions(-DBUILD_TARGET_AARCH64) add_definitions(-DBUILD_TARGET_AARCH64)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}") add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*") elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
add_definitions(-DBUILD_TARGET_ARM) add_definitions(-DBUILD_TARGET_ARM)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}") add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
add_definitions(-DBUILD_TARGET_RISCV64_LP64D) add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
add_definitions(-DBUILD_TARGET_RISCV64_LP64) add_definitions(-DBUILD_TARGET_RISCV64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D) add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
add_definitions(-DTARGET_32)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32") elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32) add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
add_definitions(-DTARGET_32)
else () else ()
message (FATAL_ERROR "-- Build target isn't set") message (FATAL_ERROR "-- Build target isn't set")
endif () endif ()
@ -98,6 +110,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions (-m32) add_definitions (-m32)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
add_definitions(-DTARGET_32)
endif () endif ()
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.malloc_func = malloc;
init_args.mem_alloc_option.allocator.realloc_func = realloc; init_args.mem_alloc_option.allocator.realloc_func = realloc;
init_args.mem_alloc_option.allocator.free_func = free; init_args.mem_alloc_option.allocator.free_func = free;
init_args.standalone = true;
/* initialize runtime environment */ /* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) { if (!wasm_runtime_full_init(&init_args)) {
@ -237,29 +238,35 @@ main(int argc, char *argv[])
goto fail1; goto fail1;
/* load WASM module */ /* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file, wasm_file_size, error_buf, if (!(wasm_module = wasm_runtime_load2(wasm_file_name, wasm_file, wasm_file_size,
sizeof(error_buf)))) { error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf); printf("%s\n", error_buf);
goto fail2; 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()); printf("%s\n", aot_get_last_error());
goto fail3; 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 WASM_ENABLE_DEBUG_AOT != 0
if (!create_dwarf_extractor(comp_data, wasm_file_name)) { if (!create_dwarf_extractor(comp_data, wasm_file_name)) {
printf("%s:create dwarf extractor failed\n", wasm_file_name); printf("%s:create dwarf extractor failed\n", wasm_file_name);
} }
#endif #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"); bh_print_time("Begin to compile");
@ -310,8 +317,8 @@ fail3:
wasm_runtime_unload(wasm_module); wasm_runtime_unload(wasm_module);
fail2: fail2:
/* free the file buffer */ /* free the file buffer */
wasm_runtime_free(wasm_file); // wasm_runtime_free(wasm_file);
fail1: fail1:
/* Destroy runtime environment */ /* Destroy runtime environment */