mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-15 08:48:33 +00:00

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>
364 lines
13 KiB
C
364 lines
13 KiB
C
#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
|