Skip to content

Commit

Permalink
Enable multi-module support for wasm-c-api (#426)
Browse files Browse the repository at this point in the history
it is allowed that all imported functions and globals can be
linked by multi-module feature automatically or by wasm-c-api manually
  • Loading branch information
lum1n0us authored Oct 16, 2020
1 parent f1fe5d7 commit 4787b15
Show file tree
Hide file tree
Showing 26 changed files with 551 additions and 186 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,18 @@ jobs:
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
make
cd .. && rm -rf build
- name: download wasi-sdk
- name: download and install wasi-sdk
run: |
cd /opt
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-8/wasi-sdk-8.0-linux.tar.gz
tar -xzf wasi-sdk-8.0-linux.tar.gz
mv wasi-sdk-8.0 wasi-sdk
- name: download and install wabt
run: |
cd /opt
wget https://github.com/WebAssembly/wabt/releases/download/1.0.19/wabt-1.0.19-ubuntu.tar.gz
tar -xzf wabt-1.0.19-ubuntu.tar.gz
mv wabt-1.0.19 wabt
- name: Build Sample [wasm-c-api]
run: |
cd samples/wasm-c-api
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ jobs:
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
make
cd .. && rm -rf build
- name: download and install wabt
run: |
cd /opt
sudo wget https://github.com/WebAssembly/wabt/releases/download/1.0.19/wabt-1.0.19-macos.tar.gz
sudo tar -xzf wabt-1.0.19-macos.tar.gz
sudo mv wabt-1.0.19 wabt
- name: Build Sample [wasm-c-api]
run: |
cd samples/wasm-c-api
Expand Down
70 changes: 47 additions & 23 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,14 @@ interp_global_set(const WASMModuleInstance *inst_interp,
const WASMGlobalInstance *global_interp =
inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data
+ global_interp->import_global_inst->data_offset
: inst_interp->global_data + global_interp->data_offset;
#else
uint8 *data = inst_interp->global_data + global_interp->data_offset;
#endif
bool ret = true;

switch (val_type_rt) {
Expand Down Expand Up @@ -1732,7 +1739,14 @@ interp_global_get(const WASMModuleInstance *inst_interp,
{
WASMGlobalInstance *global_interp = inst_interp->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
uint8 *data = global_interp->import_global_inst
? global_interp->import_module_inst->global_data
+ global_interp->import_global_inst->data_offset
: inst_interp->global_data + global_interp->data_offset;
#else
uint8 *data = inst_interp->global_data + global_interp->data_offset;
#endif
bool ret = true;

switch (val_type_rt) {
Expand Down Expand Up @@ -2080,6 +2094,7 @@ interp_link_global(const WASMModule *module_interp,
}

import->global_idx_rt = global_idx_rt;
imported_global_interp->u.global.is_linked = true;
return true;
}

Expand Down Expand Up @@ -2432,35 +2447,44 @@ wasm_instance_new(wasm_store_t *store,
}

/* link module and imports */
if (INTERP_MODE == current_runtime_mode()) {
if (imports) {
if (INTERP_MODE == current_runtime_mode()) {
#if WASM_ENABLE_INTERP != 0
import_count = ((WASMModule *)*module)->import_count;
INIT_VEC(instance->imports, wasm_extern_vec, import_count);
if (!instance->imports) {
goto failed;
}
import_count = ((WASMModule *)*module)->import_count;
INIT_VEC(instance->imports, wasm_extern_vec, import_count);
if (!instance->imports) {
goto failed;
}

import_count = interp_link(instance, (WASMModule *)*module,
(wasm_extern_t **)imports);
if (import_count) {
import_count = interp_link(instance, (WASMModule *)*module,
(wasm_extern_t **)imports);
if ((int32)import_count < 0) {
goto failed;
}
}
#endif
}
else {
#if WASM_ENABLE_AOT != 0
import_count = ((AOTModule *)*module)->import_func_count
+ ((AOTModule *)*module)->import_global_count
+ ((AOTModule *)*module)->import_memory_count
+ ((AOTModule *)*module)->import_table_count;
INIT_VEC(instance->imports, wasm_extern_vec, import_count);
if (!instance->imports) {
goto failed;
}
else {
#if WASM_ENABLE_AOT != 0
import_count = ((AOTModule *)*module)->import_func_count
+ ((AOTModule *)*module)->import_global_count
+ ((AOTModule *)*module)->import_memory_count
+ ((AOTModule *)*module)->import_table_count;
INIT_VEC(instance->imports, wasm_extern_vec, import_count);
if (!instance->imports) {
goto failed;
}

import_count =
aot_link(instance, (AOTModule *)*module, (wasm_extern_t **)imports);
if (import_count) {
import_count = aot_link(instance, (AOTModule *)*module,
(wasm_extern_t **)imports);
if ((int32)import_count < 0) {
goto failed;
}
}
#endif
}
if ((int32)import_count < 0) {
goto failed;
}
}

instance->inst_comm_rt = wasm_runtime_instantiate(
Expand Down
9 changes: 8 additions & 1 deletion core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,12 @@ wasm_runtime_destroy_loading_module_list()
}
#endif /* WASM_ENABLE_MULTI_MODULE */

bool
wasm_runtime_is_host_module(const char *module_name)
{
return strlen(module_name) == 0;
}

bool
wasm_runtime_is_built_in_module(const char *module_name)
{
Expand Down Expand Up @@ -2342,7 +2348,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
wasm_runtime_set_exception(module_inst, buf);
goto fail;
}
type = wasm_func->u.func->func_type;
type = wasm_func->is_import_func ? wasm_func->u.func_import->func_type
: wasm_func->u.func->func_type;
argc1 = wasm_func->param_cell_num;
cell_num = argc1 > wasm_func->ret_cell_num ?
argc1 : wasm_func->ret_cell_num;
Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@ void
wasm_runtime_destroy_loading_module_list();
#endif /* WASM_ENALBE_MULTI_MODULE */

bool
wasm_runtime_is_host_module(const char *module_name);

bool
wasm_runtime_is_built_in_module(const char *module_name);

Expand Down
1 change: 1 addition & 0 deletions core/iwasm/interpreter/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ typedef struct WASMGlobalImport {
bool is_mutable;
/* global data after linked */
WASMValue global_data_linked;
bool is_linked;
#if WASM_ENABLE_MULTI_MODULE != 0
/* imported function pointer after linked */
/* TODO: remove if not needed */
Expand Down
8 changes: 2 additions & 6 deletions core/iwasm/interpreter/wasm_interp_classic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,12 +1362,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* always call module own functions */
cur_func = module->functions + fidx;

if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#endif
)
cur_func_type = cur_func->u.func_import->func_type;
if (cur_func->is_import_func)
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
Expand Down
18 changes: 3 additions & 15 deletions core/iwasm/interpreter/wasm_interp_fast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1270,11 +1270,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMType *func_type;
uint32 off, ret_offset;
uint8 *ret_types;
if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#endif
)
if (cur_func->is_import_func)
func_type = cur_func->u.func_import->func_type;
else
func_type = cur_func->u.func->func_type;
Expand Down Expand Up @@ -1354,11 +1350,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* always call module own functions */
cur_func = module->functions + fidx;

if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#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;
Expand Down Expand Up @@ -3253,11 +3245,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
* values' offset so we must skip remain return values' offsets.
*/
WASMType *func_type;
if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#endif
)
if (cur_func->is_import_func)
func_type = cur_func->u.func_import->func_type;
else
func_type = cur_func->u.func->func_type;
Expand Down
67 changes: 17 additions & 50 deletions core/iwasm/interpreter/wasm_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,11 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,

declare_func_type = parent_module->types[declare_type_index];

is_built_in_module = wasm_runtime_is_built_in_module(sub_module_name);
if (is_built_in_module) {
LOG_DEBUG("%s is a function of a built-in module %s",
function_name, sub_module_name);
if (wasm_runtime_is_host_module(sub_module_name)) {
/* do nothing, wait for injecting host created fuctions */
}
else if ((is_built_in_module =
wasm_runtime_is_built_in_module(sub_module_name))) {
/* check built-in modules */
linked_func = wasm_native_resolve_symbol(sub_module_name,
function_name,
Expand All @@ -810,8 +811,6 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
}
#if WASM_ENABLE_MULTI_MODULE != 0
else {
LOG_DEBUG("%s is a function of a sub-module %s",
function_name, sub_module_name);
linked_func = wasm_loader_resolve_function(sub_module_name,
function_name,
declare_func_type,
Expand All @@ -820,19 +819,6 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
}
#endif

if (!linked_func) {
#if WASM_ENABLE_SPEC_TEST != 0
set_error_buf(error_buf, error_buf_size,
"unknown import or incompatible import type");
return false;
#else
#if WASM_ENABLE_WAMR_COMPILER == 0
LOG_WARNING("warning: fail to link import function (%s, %s)",
sub_module_name, function_name);
#endif
#endif
}

function->module_name = sub_module_name;
function->field_name = function_name;
function->func_type = declare_func_type;
Expand Down Expand Up @@ -1096,8 +1082,6 @@ load_global_import(const WASMModule *parent_module,
const uint8 *p = *p_buf, *p_end = buf_end;
uint8 declare_type = 0;
uint8 declare_mutable = 0;
bool is_mutable = false;
bool ret = false;

CHECK_BUF(p, p_end, 2);
declare_type = read_uint8(p);
Expand All @@ -1109,50 +1093,33 @@ load_global_import(const WASMModule *parent_module,
return false;
}

is_mutable = declare_mutable & 1 ? true : false;

#if WASM_ENABLE_LIBC_BUILTIN != 0
ret = wasm_runtime_is_built_in_module(sub_module_name);
if (ret) {
if (wasm_runtime_is_host_module(sub_module_name)) {
/* do nothing, let host injects the symbol */
}
else if (wasm_runtime_is_built_in_module(sub_module_name)) {
/* check built-in modules */
ret = wasm_native_lookup_libc_builtin_global(sub_module_name,
global_name, global);
if (ret) {
LOG_DEBUG("(%s, %s) is a global of a built-in module",
sub_module_name, global_name);
}
global->is_linked = wasm_native_lookup_libc_builtin_global(
sub_module_name, global_name, global);
}
#endif /* WASM_ENABLE_LIBC_BUILTIN */

#if WASM_ENABLE_MULTI_MODULE != 0
if (!ret) {
else {
/* check sub modules */
WASMGlobal *linked_global =
wasm_loader_resolve_global(sub_module_name, global_name,
declare_type, declare_mutable,
error_buf, error_buf_size);
if (linked_global) {
LOG_DEBUG("(%s, %s) is a global of external module",
sub_module_name, global_name);
global->import_module = sub_module;
global->import_global_linked = linked_global;
ret = true;
global->is_linked = true;
}
}
#endif

if (!ret) {
#if WASM_ENABLE_SPEC_TEST != 0
set_error_buf(error_buf, error_buf_size,
"unknown import or incompatible import type");
return false;
#endif
}

global->module_name = sub_module_name;
global->field_name = global_name;
global->type = declare_type;
global->is_mutable = is_mutable;
global->is_mutable = (declare_mutable == 1);
return true;
fail:
return false;
Expand Down Expand Up @@ -1363,8 +1330,7 @@ load_depended_module(const WASMModule *parent_module,
ret = reader(sub_module_name, &buffer, &buffer_size);
if (!ret) {
LOG_DEBUG("read the file of %s failed", sub_module_name);
set_error_buf_v(error_buf, error_buf_size,
"failed to read module file of %s",
set_error_buf_v(error_buf, error_buf_size, "unknown import",
sub_module_name);
goto DELETE_FROM_LOADING_LIST;
}
Expand Down Expand Up @@ -1568,7 +1534,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
LOG_DEBUG("import #%d: (%s, %s)", i, sub_module_name, field_name);
#if WASM_ENABLE_MULTI_MODULE != 0
/* assume built-in modules have been loaded */
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
if (!wasm_runtime_is_host_module(sub_module_name)
&& !wasm_runtime_is_built_in_module(sub_module_name)) {
LOG_DEBUG("%s is an exported field of a %s", field_name,
sub_module_name);
/*
Expand Down
11 changes: 1 addition & 10 deletions core/iwasm/interpreter/wasm_mini_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,19 +527,10 @@ load_global_import(const WASMModule *parent_module,
/* check built-in modules */
ret = wasm_native_lookup_libc_builtin_global(sub_module_name,
global_name, global);
if (ret) {
LOG_DEBUG("(%s, %s) is a global of a built-in module",
sub_module_name, global_name);
}
}
#endif /* WASM_ENABLE_LIBC_BUILTIN */

if (!ret) {
set_error_buf(error_buf, error_buf_size,
"unknown import or incompatible import type");
return false;
}

global->is_linked = ret;
global->module_name = sub_module_name;
global->field_name = global_name;
global->type = declare_type;
Expand Down
Loading

0 comments on commit 4787b15

Please sign in to comment.