Forráskód Böngészése

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.
Wenyong Huang 4 éve
szülő
commit
0f1ce9ef3d

+ 65 - 9
.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
+        ./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

+ 40 - 1
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 */
 

+ 4 - 1
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

+ 6 - 0
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 */

+ 0 - 7
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;

+ 8 - 0
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);

+ 11 - 16
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;
 

+ 0 - 9
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;

+ 23 - 13
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()
 

+ 1 - 0
samples/wasm-c-api/src/hello.c

@@ -112,3 +112,4 @@ int main(int argc, const char* argv[]) {
   printf("Done.\n");
   return 0;
 }
+