Skip to content

Commit 3698f22

Browse files
authored
Improve wasm-c-api instantiation-time linking (bytecodealliance#1902)
Add APIs to help prepare the imports for the wasm-c-api `wasm_instance_new`: - wasm_importtype_is_linked - wasm_runtime_is_import_func_linked - wasm_runtime_is_import_global_linked - wasm_extern_new_empty For wasm-c-api, developer may use `wasm_module_imports` to get the import types info, check whether an import func/global is linked with the above API, and ignore the linking of an import func/global with `wasm_extern_new_empty`. Sample `wasm-c-api-import` is added and document is updated.
1 parent 427abf0 commit 3698f22

File tree

16 files changed

+1156
-207
lines changed

16 files changed

+1156
-207
lines changed

core/iwasm/common/wasm_c_api.c

Lines changed: 212 additions & 203 deletions
Large diffs are not rendered by default.

core/iwasm/common/wasm_native.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
239239
return NULL;
240240
}
241241

242+
/**
243+
* allow func_type and all outputs, like p_signature, p_attachment and
244+
* p_call_conv_raw to be NULL
245+
*/
242246
void *
243247
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
244248
const WASMType *func_type, const char **p_signature,
@@ -264,10 +268,13 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
264268
node = node_next;
265269
}
266270

271+
if (!p_signature || !p_attachment || !p_call_conv_raw)
272+
return func_ptr;
273+
267274
if (func_ptr) {
268275
if (signature && signature[0] != '\0') {
269276
/* signature is not empty, check its format */
270-
if (!check_symbol_signature(func_type, signature)) {
277+
if (!func_type || !check_symbol_signature(func_type, signature)) {
271278
#if WASM_ENABLE_WAMR_COMPILER == 0
272279
/* Output warning except running aot compiler */
273280
LOG_WARNING("failed to check signature '%s' and resolve "

core/iwasm/common/wasm_runtime_common.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "bh_common.h"
88
#include "bh_assert.h"
99
#include "bh_log.h"
10+
#include "wasm_native.h"
1011
#include "wasm_runtime_common.h"
1112
#include "wasm_memory.h"
1213
#if WASM_ENABLE_INTERP != 0
@@ -5331,3 +5332,24 @@ wasm_runtime_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
53315332
*minor = WAMR_VERSION_MINOR;
53325333
*patch = WAMR_VERSION_PATCH;
53335334
}
5335+
5336+
bool
5337+
wasm_runtime_is_import_func_linked(const char *module_name,
5338+
const char *func_name)
5339+
{
5340+
return wasm_native_resolve_symbol(module_name, func_name, NULL, NULL, NULL,
5341+
NULL);
5342+
}
5343+
5344+
bool
5345+
wasm_runtime_is_import_global_linked(const char *module_name,
5346+
const char *global_name)
5347+
{
5348+
#if WASM_ENABLE_LIBC_BUILTIN != 0
5349+
WASMGlobalImport global = { 0 };
5350+
return wasm_native_lookup_libc_builtin_global(module_name, global_name,
5351+
&global);
5352+
#else
5353+
return false;
5354+
#endif
5355+
}

core/iwasm/common/wasm_runtime_common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,14 @@ void
993993
wasm_runtime_destroy_custom_sections(WASMCustomSection *section_list);
994994
#endif
995995

996+
WASM_RUNTIME_API_EXTERN bool
997+
wasm_runtime_is_import_func_linked(const char *module_name,
998+
const char *func_name);
999+
1000+
WASM_RUNTIME_API_EXTERN bool
1001+
wasm_runtime_is_import_global_linked(const char *module_name,
1002+
const char *global_name);
1003+
9961004
#ifdef __cplusplus
9971005
}
9981006
#endif

core/iwasm/include/wasm_c_api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ WASM_API_EXTERN own wasm_importtype_t* wasm_importtype_new(
354354
WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*);
355355
WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*);
356356
WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*);
357+
WASM_API_EXTERN bool wasm_importtype_is_linked(const wasm_importtype_t*);
357358

358359

359360
// Export Types
@@ -797,6 +798,9 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) {
797798

798799
#define KILOBYTE(n) ((n) * 1024)
799800

801+
// Create placeholders filled in `wasm_externvec_t* imports` for `wasm_instance_new()`
802+
WASM_API_EXTERN wasm_extern_t *wasm_extern_new_empty(wasm_store_t *, wasm_externkind_t);
803+
800804
///////////////////////////////////////////////////////////////////////////////
801805

802806
#undef own

core/iwasm/include/wasm_export.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,22 @@ wasm_runtime_get_custom_section(wasm_module_t const module_comm,
13241324
*/
13251325
WASM_RUNTIME_API_EXTERN void
13261326
wasm_runtime_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch);
1327+
1328+
/**
1329+
* Check whether an import func `(import <module_name> <func_name> (func ...))` is linked or not
1330+
* with runtime registered natvie functions
1331+
*/
1332+
WASM_RUNTIME_API_EXTERN bool
1333+
wasm_runtime_is_import_func_linked(const char *module_name,
1334+
const char *func_name);
1335+
1336+
/**
1337+
* Check whether an import global `(import <module_name> <global_name> (global ...))` is linked or not
1338+
* with runtime registered natvie globals
1339+
*/
1340+
WASM_RUNTIME_API_EXTERN bool
1341+
wasm_runtime_is_import_global_linked(const char *module_name,
1342+
const char *global_name);
13271343
/* clang-format on */
13281344

13291345
#ifdef __cplusplus

core/iwasm/interpreter/wasm_loader.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,7 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
13991399
WASMModule *sub_module = NULL;
14001400
WASMGlobal *linked_global = NULL;
14011401
#endif
1402+
bool ret = false;
14021403

14031404
CHECK_BUF(p, p_end, 2);
14041405
declare_type = read_uint8(p);
@@ -1411,15 +1412,16 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
14111412
}
14121413

14131414
#if WASM_ENABLE_LIBC_BUILTIN != 0
1414-
global->is_linked = wasm_native_lookup_libc_builtin_global(
1415-
sub_module_name, global_name, global);
1416-
if (global->is_linked) {
1415+
ret = wasm_native_lookup_libc_builtin_global(sub_module_name, global_name,
1416+
global);
1417+
if (ret) {
14171418
if (global->type != declare_type
14181419
|| global->is_mutable != declare_mutable) {
14191420
set_error_buf(error_buf, error_buf_size,
14201421
"incompatible import type");
14211422
return false;
14221423
}
1424+
global->is_linked = true;
14231425
}
14241426
#endif
14251427
#if WASM_ENABLE_MULTI_MODULE != 0
@@ -1449,6 +1451,7 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
14491451
global->is_mutable = (declare_mutable == 1);
14501452

14511453
(void)parent_module;
1454+
(void)ret;
14521455
return true;
14531456
fail:
14541457
return false;

core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
570570
#if WASM_ENABLE_LIBC_WASI != 0
571571
WASIContext *wasi_ctx;
572572
#endif
573+
CApiFuncImport **new_c_api_func_imports = NULL;
573574

574575
bh_assert(module);
575576
bh_assert(module_inst);
@@ -602,6 +603,46 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
602603
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
603604
#endif
604605

606+
/* workaround about passing instantiate-linking information */
607+
{
608+
CApiFuncImport *c_api_func_imports;
609+
uint32 import_func_count = 0;
610+
uint32 size_in_bytes = 0;
611+
612+
#if WASM_ENABLE_INTERP != 0
613+
if (module_inst->module_type == Wasm_Module_Bytecode) {
614+
new_c_api_func_imports = &(
615+
((WASMModuleInstance *)new_module_inst)->e->c_api_func_imports);
616+
c_api_func_imports =
617+
((WASMModuleInstance *)module_inst)->e->c_api_func_imports;
618+
import_func_count = ((WASMModule *)module)->import_function_count;
619+
}
620+
#endif
621+
#if WASM_ENABLE_AOT != 0
622+
if (module_inst->module_type == Wasm_Module_AoT) {
623+
AOTModuleInstanceExtra *e =
624+
(AOTModuleInstanceExtra *)((AOTModuleInstance *)new_module_inst)
625+
->e;
626+
new_c_api_func_imports = &(e->c_api_func_imports);
627+
628+
e = (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
629+
c_api_func_imports = e->c_api_func_imports;
630+
631+
import_func_count = ((AOTModule *)module)->import_func_count;
632+
}
633+
#endif
634+
635+
if (import_func_count != 0 && c_api_func_imports) {
636+
size_in_bytes = sizeof(CApiFuncImport *) * import_func_count;
637+
*new_c_api_func_imports = wasm_runtime_malloc(size_in_bytes);
638+
if (!(*new_c_api_func_imports))
639+
goto fail;
640+
641+
bh_memcpy_s(*new_c_api_func_imports, size_in_bytes,
642+
c_api_func_imports, size_in_bytes);
643+
}
644+
}
645+
605646
if (!(info_node = wasm_runtime_malloc(sizeof(ThreadInfoNode))))
606647
goto fail;
607648

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/wasm/inc/**
2+
!/wasm/inc/.*
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Copyright (C) 2019 Intel Corporation. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
cmake_minimum_required(VERSION 3.14)
5+
project(how-to-deal-with-import)
6+
7+
include(CMakePrintHelpers)
8+
include(CTest)
9+
include(ExternalProject)
10+
include(FetchContent)
11+
12+
#
13+
# dependencies
14+
#
15+
set(WAMR_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../)
16+
# wasm required headers
17+
execute_process(
18+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
19+
${WARM_ROOT}/${WAMR_ROOT}/wamr-sdk/app/libc-builtin-sysroot/include/pthread.h
20+
${CMAKE_CURRENT_LIST_DIR}/wasm/inc
21+
)
22+
23+
# vmlib
24+
################ runtime settings ################
25+
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
26+
if (APPLE)
27+
add_definitions(-DBH_PLATFORM_DARWIN)
28+
endif ()
29+
30+
# Resetdefault linker flags
31+
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
32+
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
33+
34+
# WAMR features switch
35+
36+
# Set WAMR_BUILD_TARGET, currently values supported:
37+
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
38+
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
39+
if (NOT DEFINED WAMR_BUILD_TARGET)
40+
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
41+
set (WAMR_BUILD_TARGET "AARCH64")
42+
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
43+
set (WAMR_BUILD_TARGET "RISCV64")
44+
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
45+
# Build as X86_64 by default in 64-bit platform
46+
set (WAMR_BUILD_TARGET "X86_64")
47+
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
48+
# Build as X86_32 by default in 32-bit platform
49+
set (WAMR_BUILD_TARGET "X86_32")
50+
else ()
51+
message(SEND_ERROR "Unsupported build target platform!")
52+
endif ()
53+
endif ()
54+
55+
if (NOT CMAKE_BUILD_TYPE)
56+
set (CMAKE_BUILD_TYPE Release)
57+
endif ()
58+
59+
set(WAMR_BUILD_AOT 1)
60+
set(WAMR_BUILD_INTERP 0)
61+
set(WAMR_BUILD_JIT 0)
62+
63+
set(WAMR_BUILD_FAST_INTERP 1)
64+
set(WAMR_BUILD_LIB_PTHREAD 1)
65+
set(WAMR_BUILD_LIBC_BUILTIN 1)
66+
set(WAMR_BUILD_LIBC_WASI 1)
67+
set(WAMR_BUILD_SIMD 0)
68+
69+
# compiling and linking flags
70+
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
71+
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
72+
endif ()
73+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
74+
75+
# build out vmlib
76+
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
77+
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
78+
79+
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
80+
target_link_libraries(vmlib INTERFACE dl m pthread)
81+
if(WAMR_BUILD_AOT EQUAL 1)
82+
target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_AOT=1)
83+
else()
84+
target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_AOT=0)
85+
endif()
86+
87+
if(WAMR_BUILD_INTERP EQUAL 1)
88+
target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_INTERP=1)
89+
else()
90+
target_compile_definitions(vmlib INTERFACE -DWASM_ENABLE_INTERP=0)
91+
endif()
92+
93+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
94+
# ASAN + UBSAN
95+
target_compile_options(vmlib INTERFACE -fsanitize=address,undefined)
96+
target_link_options(vmlib INTERFACE -fsanitize=address,undefined)
97+
endif()
98+
99+
# # MSAN
100+
# target_compile_options(vmlib INTERFACE -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer)
101+
# target_link_options(vmlib INTERFACE -fsanitize=memory)
102+
103+
# wamrc
104+
if(WAMR_BUILD_AOT EQUAL 1 AND WAMR_BUILD_INTERP EQUAL 0)
105+
ExternalProject_Add(wamrc
106+
PREFIX wamrc-build
107+
SOURCE_DIR ${WAMR_ROOT}/wamr-compiler
108+
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${WAMR_ROOT}/wamr-compiler -B build
109+
BUILD_COMMAND ${CMAKE_COMMAND} --build build --target wamrc
110+
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different build/wamrc ${CMAKE_CURRENT_BINARY_DIR}/wamrc
111+
)
112+
endif()
113+
114+
#
115+
# host
116+
add_subdirectory(host)
117+
add_custom_target(
118+
install_host ALL
119+
COMMAND ${CMAKE_COMMAND} -E copy_if_different ./host/example1 .
120+
DEPENDS example1
121+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
122+
)
123+
124+
# TODO: replace it with a find_package()
125+
set(WASI_SDK_DIR /opt/wasi-sdk-19.0/)
126+
set(WASI_TOOLCHAIN_FILE ${WASI_SDK_DIR}/share/cmake/wasi-sdk.cmake)
127+
set(WASI_SYS_ROOT ${WASI_SDK_DIR}/share/wasi-sysroot)
128+
129+
#
130+
# wasm
131+
if(WAMR_BUILD_AOT EQUAL 1 AND WAMR_BUILD_INTERP EQUAL 0)
132+
ExternalProject_Add(wasm
133+
PREFIX wasm-build
134+
DEPENDS wamrc
135+
BUILD_ALWAYS TRUE
136+
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/wasm
137+
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_LIST_DIR}/wasm -B build
138+
-DWASI_SDK_PREFIX=${WASI_SDK_DIR}
139+
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
140+
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
141+
-DWASM_TO_AOT=ON
142+
-DWAMRC_PATH=${CMAKE_CURRENT_BINARY_DIR}/wamrc
143+
-DSOCKET_WASI_CMAKE=${WAMR_ROOT}/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
144+
BUILD_COMMAND ${CMAKE_COMMAND} --build build
145+
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
146+
)
147+
else()
148+
ExternalProject_Add(wasm
149+
PREFIX wasm-build
150+
BUILD_ALWAYS TRUE
151+
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/wasm
152+
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_LIST_DIR}/wasm -B build
153+
-DWASI_SDK_PREFIX=${WASI_SDK_DIR}
154+
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
155+
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
156+
-DSOCKET_WASI_CMAKE=${WAMR_ROOT}/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
157+
BUILD_COMMAND ${CMAKE_COMMAND} --build build
158+
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
159+
)
160+
endif()
161+
162+
#
163+
# Test
164+
#
165+
add_test(
166+
NAME run_example1
167+
COMMAND ./example1
168+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
169+
)

0 commit comments

Comments
 (0)