From 0f1ce9ef3dd3a9ce08375e83b567fdbbdcabddc9 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 13 Jul 2021 09:01:03 +0800 Subject: [PATCH] Implement wasm-c-api frame/trap APIs for AOT mode (#663) And update CI workflow to build/cache llvm and run wasm-c-api samples. --- .github/workflows/linux.yml | 78 +++++++++++++++++++++---- core/iwasm/aot/aot_runtime.c | 41 ++++++++++++- core/iwasm/aot/aot_runtime.h | 5 +- core/iwasm/common/wasm_c_api.c | 6 ++ core/iwasm/common/wasm_c_api_internal.h | 7 --- core/iwasm/common/wasm_runtime_common.h | 8 +++ core/iwasm/interpreter/wasm_runtime.c | 27 ++++----- core/iwasm/interpreter/wasm_runtime.h | 9 --- samples/wasm-c-api/CMakeLists.txt | 36 +++++++----- samples/wasm-c-api/src/hello.c | 1 + 10 files changed, 160 insertions(+), 58 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 22d13e57..cae7b1b0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,13 +6,16 @@ name: Linux # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the main branch on: + # triggers on every branch push: - branches: [ main ] + paths-ignore: + - 'doc/**' + # triggers on every PR pull_request: - branches: [ main ] + paths-ignore: + - 'doc/**' jobs: - build: runs-on: ${{ matrix.os }} strategy: @@ -84,27 +87,80 @@ jobs: cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1 make cd .. && rm -rf build + - name: Cache LLVM libraries + uses: actions/cache@v2 + id: cache_llvm + env: + cache-name: llvm_libraries + with: + path: ./core/deps/llvm + key: ${{ runner.os }}-build-${{env.cache-name}} + restore-keys: ${{ runner.os }}-build-${{env.cache-name}} + - name: Build llvm and clang from source + if: steps.cache_llvm.outputs.cache-hit != 'true' + run: | + cd wamr-compiler + ./build_llvm.sh + - name: Build wamrc + run: | + cd wamr-compiler + mkdir build && cd build + cmake .. + make + cd .. - 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 + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-linux.tar.gz + tar -xzf wasi-sdk-12.0-linux.tar.gz + mv wasi-sdk-12.0 wasi-sdk + rm wasi-sdk-12.0-linux.tar.gz - 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 + wget https://github.com/WebAssembly/wabt/releases/download/1.0.23/wabt-1.0.23-ubuntu.tar.gz + tar -xzf wabt-1.0.23-ubuntu.tar.gz + mv wabt-1.0.23 wabt + rm wabt-1.0.23-ubuntu.tar.gz - name: Build Sample [wasm-c-api] run: | cd samples/wasm-c-api mkdir build && cd build cmake .. make - ./hello - ./global ./callback + ./callback_chain + ./global + ./hello + ./reflect + ./trap + cd .. && rm -r build + - name: Build Sample [wasm-c-api] [Jit] + run: | + cd samples/wasm-c-api + mkdir build && cd build + cmake -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_AOT=1 .. + make + ./callback + ./callback_chain + ./global + ./hello + ./reflect + ./trap + cd .. && rm -r build + - name: Build Sample [wasm-c-api] [Aot] + run: | + cd samples/wasm-c-api + mkdir build && cd build + cmake -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=1 .. + make + ./callback + ./callback_chain + ./global + ./hello + ./reflect + ./trap + cd .. && rm -r build - name: Build Sample [basic] run: | cd samples/basic diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index f03d2a11..16301f52 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1061,6 +1061,13 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, } #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (!(module_inst->frames.ptr = + runtime_malloc(sizeof(Vector), error_buf, error_buf_size))) { + goto fail; + } +#endif + /* Execute __post_instantiate function and start function*/ if (!execute_post_inst_function(module_inst) || !execute_start_function(module_inst)) { @@ -1130,6 +1137,14 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) wasm_runtime_free(module_inst->func_perf_profilings.ptr); #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (module_inst->frames.ptr) { + bh_vector_destroy(module_inst->frames.ptr); + wasm_runtime_free(module_inst->frames.ptr); + module_inst->frames.ptr = NULL; + } +#endif + if (module_inst->memories.ptr) memories_deinstantiate(module_inst); @@ -2902,7 +2917,8 @@ aot_free_frame(WASMExecEnv *exec_env) void aot_dump_call_stack(WASMExecEnv *exec_env) { - AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame; + AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame, + *first_frame = cur_frame; AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst; const char *func_name; @@ -2925,6 +2941,29 @@ aot_dump_call_stack(WASMExecEnv *exec_env) n++; } os_printf("\n"); + + /* release previous stack frames and create new ones */ + if (!bh_vector_destroy(module_inst->frames.ptr) + || !bh_vector_init(module_inst->frames.ptr, n, + sizeof(WASMCApiFrame))) { + return; + } + + cur_frame = first_frame; + while (cur_frame) { + WASMCApiFrame frame = { 0 }; + frame.instance = module_inst; + frame.module_offset = 0; + frame.func_index = cur_frame->func_index; + frame.func_offset = 0; + + if (!bh_vector_append(module_inst->frames.ptr, &frame)) { + bh_vector_destroy(module_inst->frames.ptr); + return; + } + + cur_frame = cur_frame->prev_frame; + } } #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 237764b5..af51347f 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -353,8 +353,11 @@ typedef struct AOTModuleInstance { uint32 llvm_stack; uint32 default_wasm_stack_size; + uint32 _padding; + /* store stacktrace information */ + AOTPointer frames; /* reserved */ - uint32 reserved[9]; + uint32 reserved[6]; /* * +------------------------------+ <-- memories.ptr diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 3c44c6b9..3c084ebb 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -1435,6 +1435,12 @@ wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt, trap->frames = ((WASMModuleInstance *)inst_comm_rt)->frames; } #endif + +#if WASM_ENABLE_AOT != 0 + if (inst_comm_rt->module_type == Wasm_Module_AoT) { + trap->frames = ((AOTModuleInstance *)inst_comm_rt)->frames.ptr; + } +#endif #endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */ /* allow a NULL frames list */ diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index 0e413551..dc9fc452 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -86,13 +86,6 @@ struct wasm_ref_t { uint32 obj; }; -struct wasm_frame_t { - wasm_instance_t *instance; - uint32 module_offset; - uint32 func_index; - uint32 func_offset; -}; - struct wasm_trap_t { wasm_byte_vec_t *message; Vector *frames; diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 83fd82dc..4b515bf8 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -336,6 +336,14 @@ typedef struct WASMMemoryInstanceCommon { typedef package_type_t PackageType; typedef wasm_section_t WASMSection, AOTSection; +typedef struct wasm_frame_t { + /* wasm_instance_t */ + void *instance; + uint32 module_offset; + uint32 func_index; + uint32 func_offset; +} WASMCApiFrame; + /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN bool wasm_runtime_init(void); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 5d47ba78..233468ee 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1159,6 +1159,13 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, } #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (!(module_inst->frames = runtime_malloc((uint64)sizeof(Vector), + error_buf, error_buf_size))) { + goto fail; + } +#endif + /* Instantiate global firstly to get the mutable data size */ global_count = module->import_global_count + module->global_count; if (global_count @@ -2434,13 +2441,6 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) *cur_frame = wasm_exec_env_get_cur_frame(exec_env); uint32 n = 0; - /* release previous stack frame */ - if (module_inst->frames) { - bh_vector_destroy(module_inst->frames); - wasm_runtime_free(module_inst->frames); - module_inst->frames = NULL; - } - /* count frames includes a function */ first_frame = cur_frame; while (cur_frame) { @@ -2450,14 +2450,9 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) cur_frame = cur_frame->prev_frame; } - if (!(module_inst->frames = runtime_malloc( - (uint64)sizeof(Vector), module_inst->cur_exception, 128))) { - return; - } - - if (!bh_vector_init(module_inst->frames, n, sizeof(struct WASMFrame))) { - wasm_runtime_free(module_inst->frames); - module_inst->frames = NULL; + /* release previous stack frames and create new ones */ + if (!bh_vector_destroy(module_inst->frames) + || !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame))) { return; } @@ -2465,7 +2460,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) n = 0; os_printf("\n"); while (cur_frame) { - struct WASMFrame frame = { 0 }; + WASMCApiFrame frame = { 0 }; WASMFunctionInstance *func_inst = cur_frame->function; const char *func_name = NULL; diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 473407ba..fb568812 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -150,15 +150,6 @@ typedef struct WASMExportMemInstance { } WASMExportMemInstance; #endif -#if WASM_ENABLE_DUMP_CALL_STACK != 0 -struct WASMFrame { - void *instance; - uint32 module_offset; - uint32 func_index; - uint32 func_offset; -}; -#endif - struct WASMModuleInstance { /* Module instance type, for module instance loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode; diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index d0bfffa5..2cf8d923 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -31,7 +31,7 @@ if(NOT DEFINED WAMR_BUILD_INTERP) endif() if(NOT DEFINED WAMR_BUILD_AOT) - set(WAMR_BUILD_AOT 1) + set(WAMR_BUILD_AOT 0) endif() if(NOT DEFINED WAMR_BUILD_JIT) @@ -62,7 +62,6 @@ if (NOT MSVC) endif() # build out vmlib set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) -set(WAMRC ${WAMR_ROOT_DIR}/wamr-compiler/build/wamrc) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE}) @@ -84,6 +83,19 @@ if(NOT WAT2WASM) message(SEND_ERROR "can not find wat2wasm") endif() +if(${WAMR_BUILD_AOT} EQUAL 1) + ## locate wamrc + find_program(WAMRC + wamrc + PATHS ${WAMR_ROOT_DIR}/wamr-compiler/build/ + ) + + if(NOT WAMRC) + message(SEND_ERROR "can not find wamrc. refer to \ + https://github.com/bytecodealliance/wasm-micro-runtime#build-wamrc-aot-compiler" + ) + endif() +endif() include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) set(MM_UTIL src/utils/multi_module_utils.c) @@ -120,17 +132,15 @@ foreach(EX ${EXAMPLES}) # generate .aot file if(${WAMR_BUILD_AOT} EQUAL 1) - if(EXISTS ${WAMRC}) - add_custom_target(${EX}_AOT - COMMAND ${WAMRC} -o ${PROJECT_BINARY_DIR}/${EX}.aot - ${PROJECT_BINARY_DIR}/${EX}.wasm - DEPENDS ${EX}_WASM - BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot - VERBATIM - COMMENT "generate a aot file ${PROJECT_BINARY_DIR}/${EX}.aot" - ) - add_dependencies(${EX} ${EX}_AOT) - endif() + add_custom_target(${EX}_AOT + COMMAND ${WAMRC} -o ${PROJECT_BINARY_DIR}/${EX}.aot + ${PROJECT_BINARY_DIR}/${EX}.wasm + DEPENDS ${EX}_WASM + BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot + VERBATIM + COMMENT "generate a aot file ${PROJECT_BINARY_DIR}/${EX}.aot" + ) + add_dependencies(${EX} ${EX}_AOT) endif() endforeach() diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index fde1b82d..b9dedaaf 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -112,3 +112,4 @@ int main(int argc, const char* argv[]) { printf("Done.\n"); return 0; } +