Skip to content

Commit

Permalink
feat(wasm-c-api): allow not copying the wasm binary into the module
Browse files Browse the repository at this point in the history
  • Loading branch information
eloparco committed May 6, 2024
1 parent c0e33f0 commit d1bb328
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
34 changes: 23 additions & 11 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
typedef struct wasm_module_ex_t {
struct WASMModuleCommon *module_comm_rt;
wasm_byte_vec_t *binary;
/* If true, binary in wasm_module_ex_t contains a copy of the WASM binary */
bool is_binary_cloned;
korp_mutex lock;
uint32 ref_count;
#if WASM_ENABLE_WASM_CACHE != 0
Expand Down Expand Up @@ -2234,7 +2236,7 @@ try_reuse_loaded_module(wasm_store_t *store, char *binary_hash)
#endif /* WASM_ENABLE_WASM_CACHE != 0 */

wasm_module_t *
wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
wasm_module_new_ex(wasm_store_t *store, wasm_byte_vec_t *binary,
const LoadArgs *args)
{
char error_buf[128] = { 0 };
Expand Down Expand Up @@ -2283,13 +2285,19 @@ wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
if (!module_ex)
goto quit;

module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t));
if (!module_ex->binary)
goto free_module;
module_ex->is_binary_cloned = args->clone_wasm_binary;
if (args->clone_wasm_binary) {
module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t));
if (!module_ex->binary)
goto free_module;

wasm_byte_vec_copy(module_ex->binary, binary);
if (!module_ex->binary->data)
goto free_binary;
wasm_byte_vec_copy(module_ex->binary, binary);
if (!module_ex->binary->data)
goto free_binary;
}
else {
module_ex->binary = binary;
}

module_ex->module_comm_rt = wasm_runtime_load_ex(
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, args,
Expand Down Expand Up @@ -2328,9 +2336,11 @@ wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
unload:
wasm_runtime_unload(module_ex->module_comm_rt);
free_vec:
wasm_byte_vec_delete(module_ex->binary);
if (args->clone_wasm_binary)
wasm_byte_vec_delete(module_ex->binary);
free_binary:
wasm_runtime_free(module_ex->binary);
if (args->clone_wasm_binary)
wasm_runtime_free(module_ex->binary);
free_module:
wasm_runtime_free(module_ex);
quit:
Expand All @@ -2339,10 +2349,11 @@ wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
}

wasm_module_t *
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
wasm_module_new(wasm_store_t *store, wasm_byte_vec_t *binary)
{
LoadArgs args = { 0 };
args.name = "";
args.clone_wasm_binary = true;
return wasm_module_new_ex(store, binary, &args);
}

Expand Down Expand Up @@ -2402,7 +2413,8 @@ wasm_module_delete_internal(wasm_module_t *module)
return;
}

DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete);
if (module_ex->is_binary_cloned)
DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete);

if (module_ex->module_comm_rt) {
wasm_runtime_unload(module_ex->module_comm_rt);
Expand Down
10 changes: 7 additions & 3 deletions core/iwasm/include/wasm_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,16 +527,20 @@ typedef struct WASMModuleCommon *wasm_module_t;
#define LOAD_ARGS_OPTION_DEFINED
typedef struct LoadArgs {
char *name;
/* True by default.
If false, the wasm input buffer (wasm_byte_vec_t) is referenced by the
module instead of being cloned. It should be freed exactly before calling
wasm_func_call and not before, as other Wasm C APIs use it. */
bool clone_wasm_binary;
/* TODO: more fields? */
} LoadArgs;
#endif /* LOAD_ARGS_OPTION_DEFINED */

WASM_API_EXTERN own wasm_module_t* wasm_module_new(
wasm_store_t*, const wasm_byte_vec_t* binary);
WASM_API_EXTERN own wasm_module_t* wasm_module_new(wasm_store_t*, wasm_byte_vec_t* binary);

// please refer to wasm_runtime_load_ex(...) in core/iwasm/include/wasm_export.h
WASM_API_EXTERN own wasm_module_t* wasm_module_new_ex(
wasm_store_t*, const wasm_byte_vec_t* binary, const LoadArgs *args);
wasm_store_t*, wasm_byte_vec_t* binary, const LoadArgs *args);

WASM_API_EXTERN void wasm_module_delete(own wasm_module_t*);

Expand Down
2 changes: 2 additions & 0 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ typedef struct RuntimeInitArgs {
#define LOAD_ARGS_OPTION_DEFINED
typedef struct LoadArgs {
char *name;
/* This option is only used by the Wasm C API (see wasm_c_api.h) */
bool clone_wasm_binary;
/* TODO: more fields? */
} LoadArgs;
#endif /* LOAD_ARGS_OPTION_DEFINED */
Expand Down
1 change: 1 addition & 0 deletions doc/memory_tune.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ Normally there are some methods to tune the memory usage:
- set the app heap size with `wasm_runtime_instantiate`
- use `nostdlib` mode, add `-Wl,--strip-all`: refer to [How to reduce the footprint](./build_wasm_app.md#2-how-to-reduce-the-footprint) of building wasm app for more details
- use XIP mode, refer to [WAMR XIP (Execution In Place) feature introduction](./xip.md) for more details
- when using the Wasm C API, set `clone_wasm_binary` in `LoadArgs` to `false` and free the wasm binary buffer (with `wasm_byte_vec_delete`) before wasm module execution

0 comments on commit d1bb328

Please sign in to comment.