From ff151fb7bac109636a944149e545317c4b3d798a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A4mes=20M=C3=A9n=C3=A9trey?= Date: Mon, 28 Aug 2023 03:42:16 +0200 Subject: [PATCH 01/58] sgx-ra: Disable the building of samples (#2507) --- core/iwasm/libraries/lib-rats/lib_rats.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/iwasm/libraries/lib-rats/lib_rats.cmake b/core/iwasm/libraries/lib-rats/lib_rats.cmake index 3ca08f160..e17a6b25a 100644 --- a/core/iwasm/libraries/lib-rats/lib_rats.cmake +++ b/core/iwasm/libraries/lib-rats/lib_rats.cmake @@ -23,7 +23,7 @@ include(FetchContent) set(RATS_BUILD_MODE "sgx" CACHE INTERNAL "Select build mode for librats(host|occlum|sgx|wasm)") set(RATS_INSTALL_PATH "${CMAKE_BINARY_DIR}/librats" CACHE INTERNAL "") -set(BUILD_SAMPLES OFF) +set(BUILD_SAMPLES OFF CACHE BOOL "Disable de compilation of the librats samples" FORCE) FetchContent_Declare( librats From 411b903ceeb03c1b4dd205e771be30fafc9698c9 Mon Sep 17 00:00:00 2001 From: Maks Litskevich Date: Wed, 30 Aug 2023 12:01:44 +0100 Subject: [PATCH 02/58] Add mutex stress test (#2472) As a part of stress-testing we want to ensure that mutex implementation is working correctly and protecting shared resource to be allocated from other threads when mutex is locked. This test covers the most common situations that happen when some program uses mutexes like locks from various threads, locks from the same thread etc. --- .github/workflows/nightly_run.yml | 5 + .../lib-wasi-threads/stress-test/build.sh | 65 +++++ .../errorcheck_mutex_stress_test.c | 27 +++ .../stress-test/manifest.json | 3 + .../stress-test/mutex_common.h | 229 ++++++++++++++++++ .../stress-test/normal_mutex_stress_test.c | 20 ++ .../stress-test/recursive_mutex_stress_test.c | 65 +++++ .../{test => stress-test}/spawn_stress_test.c | 2 +- .../stress_test_threads_creation.c | 6 +- .../libraries/lib-wasi-threads/test/build.sh | 5 +- .../libraries/lib-wasi-threads/test/skip.json | 6 - .../wasi-test-script/run_wasi_tests.sh | 46 ++-- 12 files changed, 442 insertions(+), 37 deletions(-) create mode 100755 core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh create mode 100644 core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c create mode 100644 core/iwasm/libraries/lib-wasi-threads/stress-test/manifest.json create mode 100644 core/iwasm/libraries/lib-wasi-threads/stress-test/mutex_common.h create mode 100644 core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c create mode 100644 core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c rename core/iwasm/libraries/lib-wasi-threads/{test => stress-test}/spawn_stress_test.c (99%) rename core/iwasm/libraries/lib-wasi-threads/{test => stress-test}/stress_test_threads_creation.c (92%) delete mode 100644 core/iwasm/libraries/lib-wasi-threads/test/skip.json diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index 0b82bb582..adedd1ef7 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -599,6 +599,11 @@ jobs: run: bash build.sh --sysroot "$SYSROOT_PATH" working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/ + - name: Build WASI thread stress tests + if: matrix.test_option == '$WASI_TEST_OPTIONS' + run: bash build.sh --sysroot "$SYSROOT_PATH" + working-directory: ./core/iwasm/libraries/lib-wasi-threads/stress-test/ + - name: build socket api tests if: matrix.test_option == '$WASI_TEST_OPTIONS' run: bash build.sh diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh b/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh new file mode 100755 index 000000000..341f3ef12 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# +# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +set -eo pipefail +CC=${CC:=/opt/wasi-sdk/bin/clang} +WAMR_DIR=../../../../.. + +show_usage() { + echo "Usage: $0 [--sysroot PATH_TO_SYSROOT]" + echo "--sysroot PATH_TO_SYSROOT specify to build with custom sysroot for wasi-libc" +} + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + --sysroot) + sysroot_path="$2" + shift + shift + ;; + --help) + show_usage + exit + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +rm -rf *.wasm +rm -rf *.aot + +for test_c in *.c; do + test_wasm="$(basename $test_c .c).wasm" + + if [[ -n "$sysroot_path" ]]; then + if [ ! -d "$sysroot_path" ]; then + echo "Directory $sysroot_path doesn't exist. Aborting" + exit 1 + fi + sysroot_command="--sysroot $sysroot_path" + fi + + echo "Compiling $test_c to $test_wasm" + $CC \ + -target wasm32-wasi-threads \ + -O2 \ + -Wall \ + -pthread \ + -z stack-size=32768 \ + -Wl,--export=__heap_base \ + -Wl,--export=__data_end \ + -Wl,--shared-memory,--max-memory=1966080 \ + -Wl,--export=wasi_thread_start \ + -Wl,--export=malloc \ + -Wl,--export=free \ + $sysroot_command \ + $test_c -o $test_wasm +done diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c new file mode 100644 index 000000000..3b594657f --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include "mutex_common.h" + +int +main() +{ + pthread_mutex_t mutex; + + // Set mutex type to errorcheck. This type provides some additional checks + // (for example returns EDEADLK instead of deadlocking in some cases) + pthread_mutexattr_t mutex_attr; + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK); + + pthread_mutex_init(&mutex, &mutex_attr); + pthread_mutexattr_destroy(&mutex_attr); + + run_common_tests(&mutex); + fprintf(stderr, "Errorcheck mutex test is completed\n"); + pthread_mutex_destroy(&mutex); +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/manifest.json b/core/iwasm/libraries/lib-wasi-threads/stress-test/manifest.json new file mode 100644 index 000000000..bb91ad083 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/manifest.json @@ -0,0 +1,3 @@ +{ + "name": "lib-wasi-threads stress tests" +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/mutex_common.h b/core/iwasm/libraries/lib-wasi-threads/stress-test/mutex_common.h new file mode 100644 index 000000000..d57ff7d50 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/mutex_common.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef MUTEX_COMMON_H +#define MUTEX_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum Constants { + NUM_ITER = 250000, + NUM_THREADS = 12, + NUM_RETRY = 8, + RETRY_SLEEP_TIME_US = 1000, +}; + +// We're counting how many times each thread was called using this array +// Main thread is also counted here so we need to make arrays bigger +typedef struct { + int tids[NUM_THREADS + 1]; + int calls[NUM_THREADS + 1]; +} StatCollector; + +typedef struct { + pthread_mutex_t *mutex; + StatCollector stat; + int counter; + bool is_sleeping; +} MutexCounter; + +// This enum defines whether thread should sleep to increase contention +enum SleepState { + NON_SLEEP = 0, + SLEEP = 1, +}; + +void +mutex_counter_init(MutexCounter *mutex_counter, pthread_mutex_t *mutex, + enum SleepState is_sleeping) +{ + memset(mutex_counter, 0, sizeof(*mutex_counter)); + mutex_counter->mutex = mutex; + mutex_counter->is_sleeping = is_sleeping; +} + +// This function spawns the thread using exponential retries if it receives +// EAGAIN +static inline void +spawn_thread(pthread_t *tid, void *func, void *arg) +{ + int status_code = -1; + int timeout_us = RETRY_SLEEP_TIME_US; + for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) { + status_code = pthread_create(tid, NULL, (void *(*)(void *))func, arg); + assert(status_code == 0 || status_code == EAGAIN); + if (status_code == EAGAIN) { + usleep(timeout_us); + timeout_us *= 2; + } + } + + assert(status_code == 0 && "Thread creation should succeed"); +} + +// This function adds tid to our stat +static inline void +add_to_stat(StatCollector *stat, int tid) +{ + int tid_num = 0; + for (; tid_num < NUM_THREADS + 1 && stat->tids[tid_num] != 0; ++tid_num) { + if (stat->tids[tid_num] == tid) { + stat->calls[tid_num]++; + return; + } + } + + assert(tid_num < NUM_THREADS + 1); + stat->tids[tid_num] = tid; + stat->calls[tid_num] = 1; +} + +// This function prints number of calls by TID +static inline void +print_stat(StatCollector *stat) +{ + fprintf(stderr, "Thread calls count by TID\n"); + for (int i = 0; i < NUM_THREADS + 1; ++i) { + if (stat->tids[i] != 0) { + fprintf(stderr, "TID: %d; Calls: %d\n", stat->tids[i], + stat->calls[i]); + } + } +} + +// This function is run by the threads, it increases counter in a loop and then +// sleeps after unlocking the mutex to provide better contention +static inline void * +inc_shared_variable(void *arg) +{ + MutexCounter *mutex_counter = (MutexCounter *)(arg); + int sleep_us = 0; + while (!pthread_mutex_lock(mutex_counter->mutex) + && mutex_counter->counter < NUM_ITER) { + mutex_counter->counter++; + add_to_stat(&mutex_counter->stat, (int)(pthread_self())); + if (mutex_counter->is_sleeping) { + sleep_us = rand() % 1000; + } + + assert(pthread_mutex_unlock(mutex_counter->mutex) == 0 + && "Should be able to unlock a mutex"); + if (mutex_counter->is_sleeping) { + usleep(sleep_us); + } + } + + assert(mutex_counter->counter == NUM_ITER); + assert(pthread_mutex_unlock(mutex_counter->mutex) == 0 + && "Should be able to unlock the mutex after test execution"); + + return NULL; +} + +// Locking and unlocking a mutex in a single thread. +static inline void * +same_thread_lock_unlock_test(void *mutex) +{ + for (int i = 0; i < NUM_ITER; ++i) { + assert(pthread_mutex_lock(mutex) == 0 + && "Main thread should be able to lock a mutex"); + assert(pthread_mutex_unlock(mutex) == 0 + && "Main thread should be able to unlock a mutex"); + } + + return NULL; +} + +// This function spawns a thread that locks and unlocks a mutex `NUM_ITER` times +// in a row +static inline void +same_non_main_thread_lock_unlock_test(pthread_mutex_t *mutex) +{ + pthread_t tid = 0; + spawn_thread(&tid, same_thread_lock_unlock_test, mutex); + + assert(tid != 0 && "TID can't be 0 after successful thread creation"); + assert(pthread_join(tid, NULL) == 0 + && "Thread should be joined successfully"); +} + +// This function checks basic contention between main and non-main thread +// increasing the shared variable +static inline void +two_threads_inc_test(pthread_mutex_t *mutex) +{ + MutexCounter mutex_counter; + mutex_counter_init(&mutex_counter, mutex, false); + + pthread_t tid = 0; + spawn_thread(&tid, inc_shared_variable, &mutex_counter); + + assert(tid != 0 && "TID can't be 0 after successful thread creation"); + inc_shared_variable(&mutex_counter); + assert(pthread_join(tid, NULL) == 0 + && "Thread should be joined without errors"); + assert(mutex_counter.counter == NUM_ITER); +} + +// This function creates number of threads specified by NUM_THREADS and run +// concurrent increasing of shared variable +static inline void +max_threads_inc_test(pthread_mutex_t *mutex, int threads_num, + enum SleepState is_sleeping) +{ + MutexCounter mutex_counter; + mutex_counter_init(&mutex_counter, mutex, is_sleeping); + + pthread_t tids[threads_num]; + for (int i = 0; i < threads_num; ++i) { + spawn_thread(&tids[i], inc_shared_variable, &mutex_counter); + } + + inc_shared_variable(&mutex_counter); + + for (int i = 0; i < threads_num; ++i) { + assert(pthread_join(tids[i], NULL) == 0 + && "Thread should be joined without errors"); + } + + print_stat(&mutex_counter.stat); +} + +// This function just runs all the tests described above +static inline void +run_common_tests(pthread_mutex_t *mutex) +{ + srand(time(NULL)); + + fprintf(stderr, "Starting same_thread_lock_unlock_test test\n"); + same_thread_lock_unlock_test(mutex); + fprintf(stderr, "Finished same_thread_lock_unlock_test test\n"); + + fprintf(stderr, "Starting same_non_main_thread_lock_unlock_test test\n"); + same_non_main_thread_lock_unlock_test(mutex); + fprintf(stderr, "Finished same_non_main_thread_lock_unlock_test test\n"); + + fprintf(stderr, "Starting two_threads_inc_test test\n"); + two_threads_inc_test(mutex); + fprintf(stderr, "Finished two_threads_inc_test test\n"); + + fprintf(stderr, "Starting max_threads_inc_test_sleep test\n"); + max_threads_inc_test(mutex, NUM_THREADS, SLEEP); + fprintf(stderr, "Finished concurrent_inc sleep test\n"); + + fprintf(stderr, "Starting max_threads_inc_test_non_sleep test\n"); + max_threads_inc_test(mutex, NUM_THREADS, NON_SLEEP); + fprintf(stderr, "Finished max_threads_inc_test test\n"); +} + +#endif // MUTEX_COMMON_H diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c new file mode 100644 index 000000000..6c75f8814 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include "mutex_common.h" + +int +main() +{ + pthread_mutex_t mutex; + pthread_mutex_init(&mutex, NULL); + + run_common_tests(&mutex); + + fprintf(stderr, "Normal mutex test is completed\n"); + pthread_mutex_destroy(&mutex); +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c new file mode 100644 index 000000000..8c3e325e8 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include "mutex_common.h" + +void +multiple_same_thread_lock(void *mutex) +{ + for (int i = 0; i < 100; ++i) { + assert(pthread_mutex_lock(mutex) == 0 + && "Recursive mutex should allow multiple locking"); + } + + for (int i = 0; i < 100; ++i) { + assert(pthread_mutex_unlock(mutex) == 0 + && "Recursive mutex should allow multiple unlocking"); + } +} + +void * +same_thread_multiple_rec_mutex_lock(void *mutex) +{ + for (int i = 0; i < NUM_ITER; ++i) { + multiple_same_thread_lock(mutex); + } + + return NULL; +} + +int +main() +{ + pthread_mutex_t mutex; + + // Set mutex type to recursive. This type allows multiple locking and + // unlocking within the same thread + pthread_mutexattr_t mutex_attr; + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&mutex, &mutex_attr); + pthread_mutexattr_destroy(&mutex_attr); + + run_common_tests(&mutex); + + fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test\n"); + same_thread_multiple_rec_mutex_lock(&mutex); + fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test\n"); + + fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test in " + "non-main thread\n"); + pthread_t tid; + spawn_thread(&tid, same_thread_multiple_rec_mutex_lock, &mutex); + assert(pthread_join(tid, NULL) == 0 + && "Non-main thread should be joined successfully"); + fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test in " + "non-main thread\n"); + + fprintf(stderr, "Recursive mutex test is completed\n"); + pthread_mutex_destroy(&mutex); +} diff --git a/core/iwasm/libraries/lib-wasi-threads/test/spawn_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c similarity index 99% rename from core/iwasm/libraries/lib-wasi-threads/test/spawn_stress_test.c rename to core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c index fa49ac481..a35337f35 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/spawn_stress_test.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c @@ -19,7 +19,7 @@ enum CONSTANTS { NUM_ITER = 100000, NUM_RETRY = 8, - MAX_NUM_THREADS = 8, + MAX_NUM_THREADS = 12, RETRY_SLEEP_TIME_US = 2000, }; diff --git a/core/iwasm/libraries/lib-wasi-threads/test/stress_test_threads_creation.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c similarity index 92% rename from core/iwasm/libraries/lib-wasi-threads/test/stress_test_threads_creation.c rename to core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c index ef148f13b..f991fa7ab 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/stress_test_threads_creation.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c @@ -12,7 +12,7 @@ enum CONSTANTS { NUM_ITER = 200000, NUM_RETRY = 8, - MAX_NUM_THREADS = 8, + MAX_NUM_THREADS = 12, RETRY_SLEEP_TIME_US = 4000, SECOND = 1000 * 1000 * 1000 }; @@ -72,7 +72,9 @@ main(int argc, char **argv) } while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) { - __builtin_wasm_memory_atomic_wait32(&threads_in_use, 0, SECOND); + // Casting to int* to supress compiler warning + __builtin_wasm_memory_atomic_wait32((int *)(&threads_in_use), 0, + SECOND); } assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0); diff --git a/core/iwasm/libraries/lib-wasi-threads/test/build.sh b/core/iwasm/libraries/lib-wasi-threads/test/build.sh index 78a081050..608dd2260 100755 --- a/core/iwasm/libraries/lib-wasi-threads/test/build.sh +++ b/core/iwasm/libraries/lib-wasi-threads/test/build.sh @@ -34,7 +34,10 @@ while [[ $# -gt 0 ]]; do done # Stress tests names -thread_start_file_exclusions=("spawn_stress_test.wasm" "linear_memory_size_update.wasm" "stress_test_threads_creation.wasm") +thread_start_file_exclusions=("linear_memory_size_update.wasm") + +rm -rf *.wasm +rm -rf *.aot for test_c in *.c; do test_wasm="$(basename $test_c .c).wasm" diff --git a/core/iwasm/libraries/lib-wasi-threads/test/skip.json b/core/iwasm/libraries/lib-wasi-threads/test/skip.json deleted file mode 100644 index 86a3ba25a..000000000 --- a/core/iwasm/libraries/lib-wasi-threads/test/skip.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lib-wasi-threads tests": { - "spawn_stress_test": "Stress tests are incompatible with the other part and executed differently", - "stress_test_threads_creation": "Stress tests are incompatible with the other part and executed differently" - } -} diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 454fbb142..37607859b 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -15,25 +15,22 @@ readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/b --allow-resolve=google-public-dns-a.google.com \ --addr-pool=::1/128,127.0.0.1/32" -readonly IWASM_CMD_STRESS="${IWASM_CMD} --max-threads=8" +readonly IWASM_CMD_STRESS="${IWASM_CMD} --max-threads=12" readonly WAMRC_CMD="${WORK_DIR}/../../../../wamr-compiler/build/wamrc" readonly C_TESTS="tests/c/testsuite/" readonly ASSEMBLYSCRIPT_TESTS="tests/assemblyscript/testsuite/" readonly THREAD_PROPOSAL_TESTS="tests/proposals/wasi-threads/" readonly THREAD_INTERNAL_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/test/" +readonly THREAD_STRESS_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/stress-test/" readonly LIB_SOCKET_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/" -readonly STRESS_TESTS=("spawn_stress_test.wasm" "stress_test_threads_creation.wasm") run_aot_tests () { local tests=("$@") - local iwasm="${IWASM_CMD}" for test_wasm in ${tests[@]}; do - local extra_stress_flags="" - for stress_test in "${STRESS_TESTS[@]}"; do - if [ "$test_wasm" == "$stress_test" ]; then - iwasm="${IWASM_CMD_STRESS}" - fi - done + local iwasm="${IWASM_CMD}" + if [[ $test_wasm =~ "stress" ]]; then + iwasm="${IWASM_CMD_STRESS}" + fi test_aot="${test_wasm%.wasm}.aot" test_json="${test_wasm%.wasm}.json" @@ -52,7 +49,7 @@ run_aot_tests () { expected=$(jq .exit_code ${test_json}) fi - ${IWASM_CMD} $extra_stress_flags $test_aot + ${iwasm} $test_aot ret=${PIPESTATUS[0]} echo "expected=$expected, actual=$ret" @@ -66,19 +63,6 @@ if [[ $MODE != "aot" ]];then python3 -m venv wasi-env && source wasi-env/bin/activate python3 -m pip install -r test-runner/requirements.txt - # Stress tests require max-threads=8 so they're executed separately - for stress_test in "${STRESS_TESTS[@]}"; do - if [[ -e "${THREAD_INTERNAL_TESTS}${stress_test}" ]]; then - echo "${stress_test}" is a stress test - ${IWASM_CMD_STRESS} ${THREAD_INTERNAL_TESTS}${stress_test} - ret=${PIPESTATUS[0]} - if [ "${ret}" -ne 0 ]; then - echo "Stress test ${stress_test} FAILED with code " ${ret} - exit_code=${ret} - fi - fi - done - TEST_RUNTIME_EXE="${IWASM_CMD}" python3 test-runner/wasi_test_runner.py \ -r adapters/wasm-micro-runtime.py \ -t \ @@ -87,12 +71,20 @@ if [[ $MODE != "aot" ]];then ${THREAD_PROPOSAL_TESTS} \ ${THREAD_INTERNAL_TESTS} \ ${LIB_SOCKET_TESTS} \ - --exclude-filter "${THREAD_INTERNAL_TESTS}skip.json" ret=${PIPESTATUS[0]} - if [ "${ret}" -ne 0 ]; then - exit_code=${ret} + + TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" python3 test-runner/wasi_test_runner.py \ + -r adapters/wasm-micro-runtime.py \ + -t \ + ${THREAD_STRESS_TESTS} + + if [ "${ret}" -eq 0 ]; then + ret=${PIPESTATUS[0]} fi + + exit_code=${ret} + deactivate else target_option="" @@ -101,7 +93,7 @@ else fi exit_code=0 - for testsuite in ${THREAD_PROPOSAL_TESTS} ${THREAD_INTERNAL_TESTS}; do + for testsuite in ${THREAD_STRESS_TESTS} ${THREAD_PROPOSAL_TESTS} ${THREAD_INTERNAL_TESTS}; do tests=$(ls ${testsuite}*.wasm) tests_array=($tests) run_aot_tests "${tests_array[@]}" From 53d7027de075073d3bc1ce7b89a4b5ef94ca7caf Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Thu, 31 Aug 2023 13:23:54 +0100 Subject: [PATCH 03/58] Implement strict validation of thread IDs according to the specification (#2521) --- .../lib-wasi-threads/test/create_threads_until_limit.c | 2 +- .../libraries/lib-wasi-threads/test/global_atomic.c | 2 +- .../libraries/lib-wasi-threads/test/global_lock.c | 2 +- .../test/trap_after_main_thread_finishes.c | 2 +- .../test/update_shared_data_and_alloc_heap.c | 2 +- samples/wasi-threads/wasm-apps/no_pthread.c | 10 ++-------- samples/wasi-threads/wasm-apps/wasi_thread_start.h | 4 ++++ 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/core/iwasm/libraries/lib-wasi-threads/test/create_threads_until_limit.c b/core/iwasm/libraries/lib-wasi-threads/test/create_threads_until_limit.c index 23ba5f627..94ffa0f67 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/create_threads_until_limit.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/create_threads_until_limit.c @@ -65,7 +65,7 @@ main(int argc, char **argv) assert(start_args_init(&data[i].base)); thread_ids[i] = __wasi_thread_spawn(&data[i]); printf("Thread created with id=%d\n", thread_ids[i]); - assert(thread_ids[i] > 0 && "Thread creation failed"); + ASSERT_VALID_TID(thread_ids[i]); for (int j = 0; j < i; j++) { assert(thread_ids[i] != thread_ids[j] && "Duplicated TIDs"); diff --git a/core/iwasm/libraries/lib-wasi-threads/test/global_atomic.c b/core/iwasm/libraries/lib-wasi-threads/test/global_atomic.c index a38e75364..7e1e8e081 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/global_atomic.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/global_atomic.c @@ -49,7 +49,7 @@ main(int argc, char **argv) for (int i = 0; i < NUM_THREADS; i++) { assert(start_args_init(&data[i].base)); thread_ids[i] = __wasi_thread_spawn(&data[i]); - assert(thread_ids[i] > 0 && "Thread creation failed"); + ASSERT_VALID_TID(thread_ids[i]); } printf("Wait for threads to finish\n"); diff --git a/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c b/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c index f81fca49b..fb33802fc 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c @@ -61,7 +61,7 @@ main(int argc, char **argv) for (int i = 0; i < NUM_THREADS; i++) { assert(start_args_init(&data[i].base)); thread_ids[i] = __wasi_thread_spawn(&data[i]); - assert(thread_ids[i] > 0 && "Thread creation failed"); + ASSERT_VALID_TID(thread_ids[i]); } printf("Wait for threads to finish\n"); diff --git a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c index 69e125d40..5cf61338f 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c @@ -38,7 +38,7 @@ main(int argc, char **argv) assert(start_args_init(&data.base)); int thread_id = __wasi_thread_spawn(&data); - assert(thread_id > 0 && "Thread creation failed"); + ASSERT_VALID_TID(thread_id); return EXIT_SUCCESS; } diff --git a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c index b7fb9afba..d6e34539b 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c @@ -69,7 +69,7 @@ main(int argc, char **argv) data[i].iteration = i; thread_ids[i] = __wasi_thread_spawn(&data[i]); - assert(thread_ids[i] > 0 && "Thread creation failed"); + ASSERT_VALID_TID(thread_ids[i]); } printf("Wait for threads to finish\n"); diff --git a/samples/wasi-threads/wasm-apps/no_pthread.c b/samples/wasi-threads/wasm-apps/no_pthread.c index dc3c95530..16661bd83 100644 --- a/samples/wasi-threads/wasm-apps/no_pthread.c +++ b/samples/wasi-threads/wasm-apps/no_pthread.c @@ -50,16 +50,11 @@ main(int argc, char **argv) } thread_id = __wasi_thread_spawn(&data); - if (thread_id < 0) { - printf("Failed to create thread: %d\n", thread_id); - ret = EXIT_FAILURE; - goto final; - } + ASSERT_VALID_TID(thread_id); if (__builtin_wasm_memory_atomic_wait32(&data.th_ready, 0, SECOND) == 2) { printf("Timeout\n"); - ret = EXIT_FAILURE; - goto final; + return EXIT_FAILURE; } printf("Thread completed, new value: %d, thread id: %d\n", data.value, @@ -67,7 +62,6 @@ main(int argc, char **argv) assert(thread_id == data.thread_id); -final: start_args_deinit(&data.base); return ret; diff --git a/samples/wasi-threads/wasm-apps/wasi_thread_start.h b/samples/wasi-threads/wasm-apps/wasi_thread_start.h index a46917d0a..2427fd2b9 100644 --- a/samples/wasi-threads/wasm-apps/wasi_thread_start.h +++ b/samples/wasi-threads/wasm-apps/wasi_thread_start.h @@ -7,6 +7,10 @@ #define STACK_SIZE 32 * 1024 // same as the main stack +/* See https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids */ +#define ASSERT_VALID_TID(TID) \ + assert(TID >= 1 && TID <= 0x1FFFFFFF && "Invalid thread ID") + typedef struct { void *stack; } start_args_t; From 382d52fc05dbb543dfafb969182104d6c4856c63 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 31 Aug 2023 21:39:08 +0900 Subject: [PATCH 04/58] Stop abusing shared memory lock to protect exception (#2509) Use a separate global lock instead. Fixes: https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 --- core/iwasm/common/wasm_runtime_common.c | 28 +---- core/iwasm/interpreter/wasm_runtime.h | 10 ++ .../libraries/thread-mgr/thread_manager.c | 111 +++++++++--------- .../libraries/thread-mgr/thread_manager.h | 2 +- 4 files changed, 75 insertions(+), 76 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 09233f249..ac85c61dc 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2377,12 +2377,7 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm) void wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) { - WASMExecEnv *exec_env = NULL; - -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (module_inst->memory_count > 0) - shared_memory_lock(module_inst->memories[0]); -#endif + exception_lock(module_inst); if (exception) { snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception), "Exception: %s", exception); @@ -2390,19 +2385,14 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) else { module_inst->cur_exception[0] = '\0'; } -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (module_inst->memory_count > 0) - shared_memory_unlock(module_inst->memories[0]); -#endif + exception_unlock(module_inst); #if WASM_ENABLE_THREAD_MGR != 0 - exec_env = + WASMExecEnv *exec_env = wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); if (exec_env) { - wasm_cluster_spread_exception(exec_env, exception ? false : true); + wasm_cluster_spread_exception(exec_env, exception); } -#else - (void)exec_env; #endif } @@ -2453,10 +2443,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf) { bool has_exception = false; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (module_inst->memory_count > 0) - shared_memory_lock(module_inst->memories[0]); -#endif + exception_lock(module_inst); if (module_inst->cur_exception[0] != '\0') { /* NULL is passed if the caller is not interested in getting the * exception content, but only in knowing if an exception has been @@ -2468,10 +2455,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf) sizeof(module_inst->cur_exception)); has_exception = true; } -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (module_inst->memory_count > 0) - shared_memory_unlock(module_inst->memories[0]); -#endif + exception_unlock(module_inst); return has_exception; } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 3e0852487..784febd44 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -668,6 +668,16 @@ void wasm_propagate_wasi_args(WASMModule *module); #endif +#if WASM_ENABLE_THREAD_MGR != 0 +void +exception_lock(WASMModuleInstance *module_inst); +void +exception_unlock(WASMModuleInstance *module_inst); +#else +#define exception_lock(module_inst) (void)(module_inst) +#define exception_unlock(module_inst) (void)(module_inst) +#endif + #ifdef __cplusplus } #endif diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 21425786a..02430fe87 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -16,10 +16,6 @@ #include "debug_engine.h" #endif -#if WASM_ENABLE_SHARED_MEMORY != 0 -#include "wasm_shared_memory.h" -#endif - typedef struct { bh_list_link l; void (*destroy_cb)(WASMCluster *); @@ -32,6 +28,8 @@ static bh_list cluster_list_head; static bh_list *const cluster_list = &cluster_list_head; static korp_mutex cluster_list_lock; +static korp_mutex _exception_lock; + typedef void (*list_visitor)(void *, void *); static uint32 cluster_max_thread_num = CLUSTER_MAX_THREAD_NUM; @@ -52,6 +50,10 @@ thread_manager_init() return false; if (os_mutex_init(&cluster_list_lock) != 0) return false; + if (os_mutex_init(&_exception_lock) != 0) { + os_mutex_destroy(&cluster_list_lock); + return false; + } return true; } @@ -66,6 +68,7 @@ thread_manager_destroy() cluster = next; } wasm_cluster_cancel_all_callbacks(); + os_mutex_destroy(&_exception_lock); os_mutex_destroy(&cluster_list_lock); } @@ -1240,72 +1243,56 @@ wasm_cluster_resume_all(WASMCluster *cluster) os_mutex_unlock(&cluster->lock); } +struct spread_exception_data { + WASMExecEnv *skip; + const char *exception; +}; + static void set_exception_visitor(void *node, void *user_data) { - WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; - WASMExecEnv *exec_env = (WASMExecEnv *)user_data; - WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env); - WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst; + const struct spread_exception_data *data = user_data; + WASMExecEnv *exec_env = (WASMExecEnv *)node; - if (curr_exec_env != exec_env) { - WASMModuleInstance *curr_wasm_inst = - (WASMModuleInstance *)get_module_inst(curr_exec_env); + if (exec_env != data->skip) { + WASMModuleInstance *wasm_inst = + (WASMModuleInstance *)get_module_inst(exec_env); - /* Only spread non "wasi proc exit" exception */ -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (curr_wasm_inst->memory_count > 0) - shared_memory_lock(curr_wasm_inst->memories[0]); -#endif - if (!strstr(wasm_inst->cur_exception, "wasi proc exit")) { - bh_memcpy_s(curr_wasm_inst->cur_exception, - sizeof(curr_wasm_inst->cur_exception), - wasm_inst->cur_exception, - sizeof(wasm_inst->cur_exception)); + exception_lock(wasm_inst); + if (data->exception != NULL) { + /* Only spread non "wasi proc exit" exception */ + if (strcmp(data->exception, "wasi proc exit")) { + snprintf(wasm_inst->cur_exception, + sizeof(wasm_inst->cur_exception), "Exception: %s", + data->exception); + } } -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (curr_wasm_inst->memory_count > 0) - shared_memory_unlock(curr_wasm_inst->memories[0]); -#endif + else { + wasm_inst->cur_exception[0] = '\0'; + } + exception_unlock(wasm_inst); /* Terminate the thread so it can exit from dead loops */ - set_thread_cancel_flags(curr_exec_env); - } -} - -static void -clear_exception_visitor(void *node, void *user_data) -{ - WASMExecEnv *exec_env = (WASMExecEnv *)user_data; - WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; - - if (curr_exec_env != exec_env) { - WASMModuleInstance *curr_wasm_inst = - (WASMModuleInstance *)get_module_inst(curr_exec_env); - -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (curr_wasm_inst->memory_count > 0) - shared_memory_lock(curr_wasm_inst->memories[0]); -#endif - curr_wasm_inst->cur_exception[0] = '\0'; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (curr_wasm_inst->memory_count > 0) - shared_memory_unlock(curr_wasm_inst->memories[0]); -#endif + if (data->exception != NULL) { + set_thread_cancel_flags(exec_env); + } } } void -wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear) +wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception) { + const bool has_exception = exception != NULL; WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env); bh_assert(cluster); + struct spread_exception_data data; + data.skip = exec_env; + data.exception = exception; + os_mutex_lock(&cluster->lock); - cluster->has_exception = !clear; - traverse_list(&cluster->exec_env_list, - clear ? clear_exception_visitor : set_exception_visitor, - exec_env); + cluster->has_exception = has_exception; + traverse_list(&cluster->exec_env_list, set_exception_visitor, &data); os_mutex_unlock(&cluster->lock); } @@ -1353,3 +1340,21 @@ wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env) return is_thread_terminated; } + +void +exception_lock(WASMModuleInstance *module_inst) +{ + /* + * Note: this lock could be per module instance if desirable. + * We can revisit on AOT version bump. + * It probably doesn't matter though because the exception handling + * logic should not be executed too frequently anyway. + */ + os_mutex_lock(&_exception_lock); +} + +void +exception_unlock(WASMModuleInstance *module_inst) +{ + os_mutex_unlock(&_exception_lock); +} diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 2060869c2..c6bc7a526 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -139,7 +139,7 @@ WASMExecEnv * wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst); void -wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear); +wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception); WASMExecEnv * wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env); From 1ff41ebdc257b45c9f574d8d1f7ee6df4be79645 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 1 Sep 2023 13:10:54 +0900 Subject: [PATCH 05/58] Implement os_usleep for posix (#2517) --- .../platform/common/posix/posix_sleep.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 core/shared/platform/common/posix/posix_sleep.c diff --git a/core/shared/platform/common/posix/posix_sleep.c b/core/shared/platform/common/posix/posix_sleep.c new file mode 100644 index 000000000..fa0645037 --- /dev/null +++ b/core/shared/platform/common/posix/posix_sleep.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +#include "platform_api_extension.h" + +int +os_usleep(uint32 usec) +{ + struct timespec ts; + int ret; + + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + ret = nanosleep(&ts, NULL); + return ret == 0 ? 0 : -1; +} From 8c2dc1d011b39950a4fd29ae9b032b1c1424a6e1 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Mon, 4 Sep 2023 06:21:10 +0100 Subject: [PATCH 06/58] Add unit tests for the tid allocator (#2519) Add simple infrastructure to add more unit tests in the future. At the moment tests are only executed on Linux, but can be extended to other platforms if needed. Use https://github.com/google/googletest/ as a framework. --- .../compilation_on_android_ubuntu.yml | 12 +++- .../lib-wasi-threads/tid_allocator.h | 10 +++ .../lib_wasi_threads_unit_tests.cmake | 6 ++ .../unit-test/test_tid_allocator.cpp | 62 +++++++++++++++++++ tests/unit/CMakeLists.txt | 51 +++++++++++++++ tests/unit/main.cpp | 21 +++++++ 6 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 core/iwasm/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake create mode 100644 core/iwasm/libraries/lib-wasi-threads/unit-test/test_tid_allocator.cpp create mode 100644 tests/unit/CMakeLists.txt create mode 100644 tests/unit/main.cpp diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index b7ac084eb..927ef4d75 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -72,7 +72,7 @@ jobs: with: os: "ubuntu-22.04" arch: "X86" - + build_wamrc: needs: [build_llvm_libraries_on_ubuntu_2204] @@ -241,6 +241,14 @@ jobs: cmake --build . --config Release --parallel 4 working-directory: product-mini/platforms/${{ matrix.platform }} + - name: Build and run unit tests + run: | + mkdir build-unittests && cd build-unittests + cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} + cmake --build . --config Release --parallel 4 + ctest + working-directory: tests/unit + build_samples_wasm_c_api: needs: [ @@ -483,7 +491,7 @@ jobs: sudo tar -xzf wasi-sdk-*.tar.gz sudo mv wasi-sdk-20.0 wasi-sdk - # It is a temporary solution until new wasi-sdk that includes bug fixes is released + # It is a temporary solution until new wasi-sdk that includes bug fixes is released - name: build wasi-libc from source if: matrix.test_option == '$WASI_TEST_OPTIONS' run: | diff --git a/core/iwasm/libraries/lib-wasi-threads/tid_allocator.h b/core/iwasm/libraries/lib-wasi-threads/tid_allocator.h index 53af1719f..6e25f7749 100644 --- a/core/iwasm/libraries/lib-wasi-threads/tid_allocator.h +++ b/core/iwasm/libraries/lib-wasi-threads/tid_allocator.h @@ -8,8 +8,14 @@ #include "platform_common.h" +#ifdef __cplusplus +extern "C" { +#endif + #define TID_ALLOCATOR_INIT_SIZE CLUSTER_MAX_THREAD_NUM enum { + /* Keep it in sync with + https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids */ TID_MIN = 1, TID_MAX = 0x1FFFFFFF }; // Reserved TIDs (WASI specification) @@ -33,4 +39,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator); void tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id); +#ifdef __cplusplus +} +#endif + #endif /* _TID_ALLOCATOR_H */ \ No newline at end of file diff --git a/core/iwasm/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake b/core/iwasm/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake new file mode 100644 index 000000000..75d8f4e0e --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake @@ -0,0 +1,6 @@ +# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +create_wamr_unit_test(wasi_threads + ${CMAKE_CURRENT_LIST_DIR}/test_tid_allocator.cpp +) diff --git a/core/iwasm/libraries/lib-wasi-threads/unit-test/test_tid_allocator.cpp b/core/iwasm/libraries/lib-wasi-threads/unit-test/test_tid_allocator.cpp new file mode 100644 index 000000000..6fa7300f6 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/unit-test/test_tid_allocator.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +#include "tid_allocator.h" + +#include + +class TidAllocatorTest : public ::testing::Test +{ + protected: + void SetUp() override { ASSERT_TRUE(tid_allocator_init(&_allocator)); } + + void TearDown() override { tid_allocator_deinit(&_allocator); } + + TidAllocator _allocator; +}; + +static bool +is_tid_valid(int32 tid) +{ + /* See: https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids + */ + return tid >= TID_MIN && tid <= TID_MAX; +} + +TEST_F(TidAllocatorTest, BasicTest) +{ + int32 tid = tid_allocator_get_tid(&_allocator); + + ASSERT_TRUE(is_tid_valid(tid)); +} + +TEST_F(TidAllocatorTest, ShouldFailOnAllocatingMoreThanAllowedThreadIDs) +{ + int32 last_tid = 0; + for (int32 i = 0; i < TID_MAX + 1; i++) { + last_tid = tid_allocator_get_tid(&_allocator); + if (last_tid < 0) { + break; + } + ASSERT_TRUE(is_tid_valid(last_tid)); + } + + ASSERT_LT(last_tid, 0); +} + +TEST_F(TidAllocatorTest, ShouldAllocateMoreThanAllowedTIDsIfOldTIDsAreReleased) +{ + int32 last_tid = 0; + for (int32 i = 0; i < TID_MAX + 1; i++) { + if (last_tid != 0) { + tid_allocator_release_tid(&_allocator, last_tid); + } + + last_tid = tid_allocator_get_tid(&_allocator); + ASSERT_TRUE(is_tid_valid(last_tid)); + } +} diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt new file mode 100644 index 000000000..a9a7b8776 --- /dev/null +++ b/tests/unit/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 3.14) + +project (wamr_unit_tests) + +include (CTest) + +if (NOT DEFINED WAMR_BUILD_INTERP) + # Enable Interpreter by default + set (WAMR_BUILD_INTERP 1) +endif () + +if (NOT DEFINED WAMR_BUILD_PLATFORM) + string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) +endif () + +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) +add_library (vmlib ${WAMR_RUNTIME_LIB_SOURCE}) + +include (FetchContent) +FetchContent_Declare ( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set (gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable (googletest) + +include (GoogleTest) + +add_library (wamr_gtest_main main.cpp) +target_link_libraries (wamr_gtest_main PUBLIC gtest vmlib) + +function (create_wamr_unit_test test_name) + set (sources ${ARGN}) + add_executable (${test_name} ${sources}) + target_link_libraries ( + ${test_name} + wamr_gtest_main + vmlib + ${LLVM_AVAILABLE_LIBS} + ) + gtest_discover_tests (${test_name}) + endfunction () + +if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1) + include (${IWASM_DIR}/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake) +endif () diff --git a/tests/unit/main.cpp b/tests/unit/main.cpp new file mode 100644 index 000000000..63695d9ee --- /dev/null +++ b/tests/unit/main.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ +#include +#include "wasm_runtime_common.h" + +int +main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + if (!wasm_runtime_init()) { + return -1; + } + + int ret = RUN_ALL_TESTS(); + wasm_runtime_destroy(); + + return ret; +} \ No newline at end of file From 2e78230e0655bcb8efc040b51b6a9b8ee1c31f45 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 4 Sep 2023 17:52:19 +0900 Subject: [PATCH 07/58] set_exception_visitor: Remove the special case for wasi proc exit (#2525) While wasi proc exit is not a real trap, what the runtime does on it is mostly same as real traps. That is, kill the siblings threads and represent the exit/trap as the result of the "process" to the user api. There seems no reason to distinguish it from real traps here. Note that: - The target thread either doesn't care the specific exception type or ignore wasi proc exit by themselves. (clear_wasi_proc_exit_exception) - clear_wasi_proc_exit_exception only clears local exception. --- core/iwasm/libraries/thread-mgr/thread_manager.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 02430fe87..9a1e82d31 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -1260,12 +1260,8 @@ set_exception_visitor(void *node, void *user_data) exception_lock(wasm_inst); if (data->exception != NULL) { - /* Only spread non "wasi proc exit" exception */ - if (strcmp(data->exception, "wasi proc exit")) { - snprintf(wasm_inst->cur_exception, - sizeof(wasm_inst->cur_exception), "Exception: %s", - data->exception); - } + snprintf(wasm_inst->cur_exception, sizeof(wasm_inst->cur_exception), + "Exception: %s", data->exception); } else { wasm_inst->cur_exception[0] = '\0'; From 9e3904337edc025f490dde7ad86693f54d3cb761 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 4 Sep 2023 19:01:09 +0900 Subject: [PATCH 08/58] Revert "Return error when exception was raised after main thread finishes" (#2524) This reverts commit 71d43f3ca18b96c983d0fa8ca45ea658d6f9ee4a. --- .../test/trap_after_main_thread_finishes.json | 3 --- product-mini/platforms/posix/main.c | 6 +----- product-mini/platforms/windows/main.c | 6 +----- 3 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json diff --git a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json deleted file mode 100644 index 9dc1e30d2..000000000 --- a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "exit_code": 1 -} diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 5d20fd293..6d4ada662 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -921,12 +921,8 @@ main(int argc, char *argv[]) #if WASM_ENABLE_LIBC_WASI != 0 if (ret == 0) { - /* wait for threads to finish and propagate wasi exit code. */ + /* propagate wasi exit code. */ ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst); - if (wasm_runtime_get_exception(wasm_module_inst)) { - /* got an exception in spawned thread */ - ret = 1; - } } #endif diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index b7cf81433..8b1b1f371 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -554,12 +554,8 @@ main(int argc, char *argv[]) #if WASM_ENABLE_LIBC_WASI != 0 if (ret == 0) { - /* wait for threads to finish and propagate wasi exit code. */ + /* propagate wasi exit code. */ ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst); - if (wasm_runtime_get_exception(wasm_module_inst)) { - /* got an exception in spawned thread */ - ret = 1; - } } #endif From 48b71a05fbbee26524e50a5d1df0ca77cb39e580 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 4 Sep 2023 20:14:56 +0900 Subject: [PATCH 09/58] libc-wasi: Remove unused code (#2528) --- .../include/wasmtime_ssp.h | 45 ------- .../sandboxed-system-primitives/src/posix.c | 117 ------------------ .../src/ssp_config.h | 6 - 3 files changed, 168 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h index 586e5816d..576ffcf30 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h @@ -264,37 +264,6 @@ typedef uint8_t __wasi_sdflags_t; typedef uint16_t __wasi_siflags_t; typedef uint8_t __wasi_signal_t; -// 0 is reserved; POSIX has special semantics for kill(pid, 0). -#define __WASI_SIGHUP (1) -#define __WASI_SIGINT (2) -#define __WASI_SIGQUIT (3) -#define __WASI_SIGILL (4) -#define __WASI_SIGTRAP (5) -#define __WASI_SIGABRT (6) -#define __WASI_SIGBUS (7) -#define __WASI_SIGFPE (8) -#define __WASI_SIGKILL (9) -#define __WASI_SIGUSR1 (10) -#define __WASI_SIGSEGV (11) -#define __WASI_SIGUSR2 (12) -#define __WASI_SIGPIPE (13) -#define __WASI_SIGALRM (14) -#define __WASI_SIGTERM (15) -#define __WASI_SIGCHLD (16) -#define __WASI_SIGCONT (17) -#define __WASI_SIGSTOP (18) -#define __WASI_SIGTSTP (19) -#define __WASI_SIGTTIN (20) -#define __WASI_SIGTTOU (21) -#define __WASI_SIGURG (22) -#define __WASI_SIGXCPU (23) -#define __WASI_SIGXFSZ (24) -#define __WASI_SIGVTALRM (25) -#define __WASI_SIGPROF (26) -#define __WASI_SIGWINCH (27) -#define __WASI_SIGPOLL (28) -#define __WASI_SIGPWR (29) -#define __WASI_SIGSYS (30) typedef uint16_t __wasi_subclockflags_t; #define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001) @@ -986,20 +955,6 @@ __wasi_errno_t wasmtime_ssp_poll_oneoff( size_t *nevents ) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) __attribute__((__warn_unused_result__)); -#if 0 -/** - * We throw exception in libc-wasi wrapper function wasi_proc_exit() - * but not call this function. - */ -_Noreturn void wasmtime_ssp_proc_exit( - __wasi_exitcode_t rval -) WASMTIME_SSP_SYSCALL_NAME(proc_exit); -#endif - -__wasi_errno_t wasmtime_ssp_proc_raise( - __wasi_signal_t sig -) WASMTIME_SSP_SYSCALL_NAME(proc_raise) __attribute__((__warn_unused_result__)); - __wasi_errno_t wasmtime_ssp_random_get( void *buf, size_t buf_len diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 3038e3d44..6fef381df 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -2787,123 +2787,6 @@ wasmtime_ssp_poll_oneoff( return error; } -#if 0 -/** - * We throw exception in libc-wasi wrapper function wasi_proc_exit() - * but not call this function. - */ -void wasmtime_ssp_proc_exit( - __wasi_exitcode_t rval -) { - _Exit((int32)rval); -} -#endif - -__wasi_errno_t -wasmtime_ssp_proc_raise(__wasi_signal_t sig) -{ - static const int signals[] = { -#define X(v) [__WASI_##v] = v -#if defined(SIGABRT) - X(SIGABRT), -#endif -#if defined(SIGALRM) - X(SIGALRM), -#endif -#if defined(SIGBUS) - X(SIGBUS), -#endif -#if defined(SIGCHLD) - X(SIGCHLD), -#endif -#if defined(SIGCONT) - X(SIGCONT), -#endif -#if defined(SIGFPE) - X(SIGFPE), -#endif -#if defined(SIGHUP) - X(SIGHUP), -#endif -#if defined(SIGILL) - X(SIGILL), -#endif -#if defined(SIGINT) - X(SIGINT), -#endif -#if defined(SIGKILL) - X(SIGKILL), -#endif -#if defined(SIGPIPE) - X(SIGPIPE), -#endif -#if defined(SIGQUIT) - X(SIGQUIT), -#endif -#if defined(SIGSYS) - X(SIGSEGV), -#endif -#if defined(SIGSTOP) - X(SIGSTOP), -#endif -#if defined(SIGSYS) - X(SIGSYS), -#endif -#if defined(SIGTERM) - X(SIGTERM), -#endif -#if defined(SIGTRAP) - X(SIGTRAP), -#endif -#if defined(SIGTSTP) - X(SIGTSTP), -#endif -#if defined(SIGTTIN) - X(SIGTTIN), -#endif -#if defined(SIGTTOU) - X(SIGTTOU), -#endif -#if defined(SIGURG) - X(SIGURG), -#endif -#if defined(SIGUSR1) - X(SIGUSR1), -#endif -#if defined(SIGUSR2) - X(SIGUSR2), -#endif -#if defined(SIGVTALRM) - X(SIGVTALRM), -#endif -#if defined(SIGXCPU) - X(SIGXCPU), -#endif -#if defined(SIGXFSZ) - X(SIGXFSZ), -#endif -#undef X - }; - if (sig >= sizeof(signals) / sizeof(signals[0]) || signals[sig] == 0) - return __WASI_EINVAL; - -#if CONFIG_TLS_USE_GSBASE - // TLS on OS X depends on installing a SIGSEGV handler. Reset SIGSEGV - // to the default action before raising. - if (sig == __WASI_SIGSEGV) { - struct sigaction sa = { - .sa_handler = SIG_DFL, - }; - sigemptyset(&sa.sa_mask); - sigaction(SIGSEGV, &sa, NULL); - } -#endif - - if (raise(signals[sig]) < 0) - return convert_errno(errno); - return 0; -} - __wasi_errno_t wasmtime_ssp_random_get(void *buf, size_t nbyte) { diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 7f6e9b941..f5e130a9e 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -101,12 +101,6 @@ #define st_mtim st_mtimespec #endif -#ifdef __APPLE__ -#define CONFIG_TLS_USE_GSBASE 1 -#else -#define CONFIG_TLS_USE_GSBASE 0 -#endif - #if !defined(BH_PLATFORM_LINUX_SGX) /* Clang's __GNUC_PREREQ macro has a different meaning than GCC one, so we have to handle this case specially */ From 709127d631aeef901ecca617439766935abeecc6 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Tue, 5 Sep 2023 10:41:52 +0200 Subject: [PATCH 10/58] Add callback to handle memory.grow failures (#2522) When embedding WAMR, this PR allows to register a callback that is invoked when memory.grow fails. In case of memory allocation failures, some languages allow to handle the error (e.g. by checking the return code of malloc/calloc in C), some others (e.g. Rust) just panic. --- core/iwasm/aot/aot_runtime.c | 3 + core/iwasm/common/wasm_memory.c | 107 ++++++++++++++++++++++---- core/iwasm/common/wasm_memory.h | 4 + core/iwasm/include/wasm_export.h | 17 ++++ core/iwasm/interpreter/wasm_runtime.c | 3 + core/iwasm/interpreter/wasm_runtime.h | 2 + 6 files changed, 119 insertions(+), 17 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 2c647d345..55c399a8b 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1443,6 +1443,9 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, /* set thread handle and stack boundary */ wasm_exec_env_set_thread_info(exec_env); + /* set exec env so it can be later retrieved from instance */ + ((AOTModuleInstanceExtra *)module_inst->e)->common.cur_exec_env = exec_env; + if (ext_ret_count > 0) { uint32 cell_num = 0, i; uint8 *ext_ret_types = func_type->types + func_type->param_count + 1; diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 7d5cb4353..a083a214e 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -8,6 +8,7 @@ #include "../aot/aot_runtime.h" #include "bh_platform.h" #include "mem_alloc.h" +#include "wasm_memory.h" #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" @@ -24,6 +25,8 @@ static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN; static mem_allocator_t pool_allocator = NULL; +static enlarge_memory_error_callback_t enlarge_memory_error_cb; + #if WASM_MEM_ALLOC_WITH_USER_DATA != 0 static void *allocator_user_data = NULL; static void *(*malloc_func)(void *user_data, unsigned int size) = NULL; @@ -570,13 +573,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) { WASMMemoryInstance *memory = wasm_get_default_memory(module); uint8 *memory_data_old, *memory_data_new, *heap_data_old; - uint32 num_bytes_per_page, heap_size, total_size_old; + uint32 num_bytes_per_page, heap_size, total_size_old = 0; uint32 cur_page_count, max_page_count, total_page_count; uint64 total_size_new; bool ret = true; + enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR; - if (!memory) - return false; + if (!memory) { + ret = false; + goto return_func; + } heap_data_old = memory->heap_data; heap_size = (uint32)(memory->heap_data_end - memory->heap_data); @@ -594,9 +600,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) /* No need to enlarge memory */ return true; - if (total_page_count < cur_page_count /* integer overflow */ - || total_page_count > max_page_count) { - return false; + if (total_page_count < cur_page_count) { /* integer overflow */ + ret = false; + goto return_func; + } + + if (total_page_count > max_page_count) { + failure_reason = MAX_SIZE_REACHED; + ret = false; + goto return_func; } bh_assert(total_size_new <= 4 * (uint64)BH_GB); @@ -622,14 +634,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) if (heap_size > 0) { if (mem_allocator_is_heap_corrupted(memory->heap_handle)) { wasm_runtime_show_app_heap_corrupted_prompt(); - return false; + ret = false; + goto return_func; } } if (!(memory_data_new = wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) { if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) { - return false; + ret = false; + goto return_func; } if (memory_data_old) { bh_memcpy_s(memory_data_new, (uint32)total_size_new, @@ -685,6 +699,26 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) os_writegsbase(memory_data_new); #endif +return_func: + if (!ret && enlarge_memory_error_cb) { + WASMExecEnv *exec_env = NULL; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) + exec_env = + ((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env; +#endif +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) + exec_env = + ((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env; +#endif + + enlarge_memory_error_cb(inc_page_count, total_size_old, 0, + failure_reason, + (WASMModuleInstanceCommon *)module, exec_env); + } + return ret; } #else @@ -692,12 +726,16 @@ bool wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) { WASMMemoryInstance *memory = wasm_get_default_memory(module); - uint32 num_bytes_per_page, total_size_old; + uint32 num_bytes_per_page, total_size_old = 0; uint32 cur_page_count, max_page_count, total_page_count; uint64 total_size_new; + bool ret = true; + enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR; - if (!memory) - return false; + if (!memory) { + ret = false; + goto return_func; + } num_bytes_per_page = memory->num_bytes_per_page; cur_page_count = memory->cur_page_count; @@ -710,9 +748,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) /* No need to enlarge memory */ return true; - if (total_page_count < cur_page_count /* integer overflow */ - || total_page_count > max_page_count) { - return false; + if (total_page_count < cur_page_count) { /* integer overflow */ + ret = false; + goto return_func; + } + + if (total_page_count > max_page_count) { + failure_reason = MAX_SIZE_REACHED; + ret = false; + goto return_func; } bh_assert(total_size_new <= 4 * (uint64)BH_GB); @@ -727,7 +771,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) if (!os_mem_commit(memory->memory_data_end, (uint32)total_size_new - total_size_old, MMAP_PROT_READ | MMAP_PROT_WRITE)) { - return false; + ret = false; + goto return_func; } #endif @@ -739,7 +784,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) os_mem_decommit(memory->memory_data_end, (uint32)total_size_new - total_size_old); #endif - return false; + ret = false; + goto return_func; } /* The increased pages are filled with zero by the OS when os_mmap, @@ -759,10 +805,37 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->mem_bound_check_16bytes.u64 = total_size_new - 16; #endif - return true; +return_func: + if (!ret && enlarge_memory_error_cb) { + WASMExecEnv *exec_env = NULL; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) + exec_env = + ((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env; +#endif +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) + exec_env = + ((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env; +#endif + + enlarge_memory_error_cb(inc_page_count, total_size_old, 0, + failure_reason, + (WASMModuleInstanceCommon *)module, exec_env); + } + + return ret; } #endif /* end of OS_ENABLE_HW_BOUND_CHECK */ +void +wasm_runtime_set_enlarge_mem_error_callback( + const enlarge_memory_error_callback_t callback) +{ + enlarge_memory_error_cb = callback; +} + bool wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) { diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index 516ee8497..cf7d7ffcd 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -24,6 +24,10 @@ wasm_runtime_memory_destroy(); unsigned wasm_runtime_memory_pool_size(); +void +wasm_runtime_set_enlarge_mem_error_callback( + const enlarge_memory_error_callback_t callback); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 18e15782f..79edc68ed 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1439,6 +1439,23 @@ WASM_RUNTIME_API_EXTERN bool wasm_runtime_is_import_global_linked(const char *module_name, const char *global_name); +typedef enum { + INTERNAL_ERROR, + MAX_SIZE_REACHED, +} enlarge_memory_error_reason_t; + +typedef void (*enlarge_memory_error_callback_t)( + uint32_t inc_page_count, uint64_t current_memory_size, + uint32_t memory_index, enlarge_memory_error_reason_t failure_reason, + wasm_module_inst_t instance, wasm_exec_env_t exec_env); + +/** + * Setup callback invoked when memory.grow fails + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_enlarge_mem_error_callback( + const enlarge_memory_error_callback_t callback); + /* clang-format on */ #ifdef __cplusplus diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index b71b608a2..f395b1eaa 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2400,6 +2400,9 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function, /* set thread handle and stack boundary */ wasm_exec_env_set_thread_info(exec_env); + /* set exec env so it can be later retrieved from instance */ + module_inst->e->common.cur_exec_env = exec_env; + interp_call_wasm(module_inst, exec_env, function, argc, argv); return !wasm_copy_exception(module_inst, NULL); } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 784febd44..aa33dc18c 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -213,6 +213,8 @@ typedef struct CApiFuncImport { /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */ typedef struct WASMModuleInstanceExtraCommon { CApiFuncImport *c_api_func_imports; + /* pointer to the exec env currently used */ + WASMExecEnv *cur_exec_env; #if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0 /* Disable bounds checks or not */ bool disable_bounds_checks; From 4798b69f36058cfb438e8a3181726f00726b7d95 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Wed, 6 Sep 2023 06:17:16 +0100 Subject: [PATCH 11/58] Add ARM aeabi symbol for clearing memory content in a specific range (#2531) --- core/iwasm/aot/arch/aot_reloc_arm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/aot/arch/aot_reloc_arm.c b/core/iwasm/aot/arch/aot_reloc_arm.c index fbf9be13c..5d79e8a68 100644 --- a/core/iwasm/aot/arch/aot_reloc_arm.c +++ b/core/iwasm/aot/arch/aot_reloc_arm.c @@ -40,6 +40,7 @@ void __aeabi_ldivmod(); void __aeabi_memcpy(); void __aeabi_memmove(); void __aeabi_memset(); +void __aeabi_memclr(); void __aeabi_uidiv(); void __aeabi_uidivmod(); void __aeabi_ul2d(); @@ -126,6 +127,7 @@ static SymbolMap target_sym_map[] = { REG_SYM(__aeabi_memcpy), REG_SYM(__aeabi_memmove), REG_SYM(__aeabi_memset), + REG_SYM(__aeabi_memclr), REG_SYM(__aeabi_uidiv), REG_SYM(__aeabi_uidivmod), REG_SYM(__aeabi_ul2d), From 151dfae49cc1b62aa52857d9b558b50b1b24841a Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 6 Sep 2023 16:25:58 +0900 Subject: [PATCH 12/58] Unifdef -U WASMTIME_SSP_STATIC_CURFDS (#2533) The macro WASMTIME_SSP_STATIC_CURFDS isn't used in the source code, remove the related macro control code. --- .../include/wasmtime_ssp.h | 190 ------- .../sandboxed-system-primitives/src/posix.c | 522 ++++++------------ 2 files changed, 166 insertions(+), 546 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h index 576ffcf30..a53153552 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h @@ -598,17 +598,13 @@ typedef struct __wasi_addr_info_hints_t { #endif __wasi_errno_t wasmtime_ssp_args_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct argv_environ_values *arg_environ, -#endif char **argv, char *argv_buf ) WASMTIME_SSP_SYSCALL_NAME(args_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_args_sizes_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct argv_environ_values *arg_environ, -#endif size_t *argc, size_t *argv_buf_size ) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) __attribute__((__warn_unused_result__)); @@ -625,57 +621,43 @@ __wasi_errno_t wasmtime_ssp_clock_time_get( ) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_environ_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct argv_environ_values *arg_environ, -#endif char **environ, char *environ_buf ) WASMTIME_SSP_SYSCALL_NAME(environ_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_environ_sizes_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct argv_environ_values *arg_environ, -#endif size_t *environ_count, size_t *environ_buf_size ) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_prestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_prestats *prestats, -#endif __wasi_fd_t fd, __wasi_prestat_t *buf ) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_prestat_dir_name( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_prestats *prestats, -#endif __wasi_fd_t fd, char *path, size_t path_len ) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_close( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct fd_prestats *prestats, -#endif __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_datasync( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_pread( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const __wasi_iovec_t *iovs, size_t iovs_len, @@ -684,9 +666,7 @@ __wasi_errno_t wasmtime_ssp_fd_pread( ) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_pwrite( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const __wasi_ciovec_t *iovs, size_t iovs_len, @@ -695,9 +675,7 @@ __wasi_errno_t wasmtime_ssp_fd_pwrite( ) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_read( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const __wasi_iovec_t *iovs, size_t iovs_len, @@ -705,18 +683,14 @@ __wasi_errno_t wasmtime_ssp_fd_read( ) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_renumber( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct fd_prestats *prestats, -#endif __wasi_fd_t from, __wasi_fd_t to ) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_seek( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filedelta_t offset, __wasi_whence_t whence, @@ -724,49 +698,37 @@ __wasi_errno_t wasmtime_ssp_fd_seek( ) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_tell( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filesize_t *newoffset ) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_fdstat_t *buf ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_fdflags_t flags ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_rights_t fs_rights_base, __wasi_rights_t fs_rights_inheriting ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_sync( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_write( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const __wasi_ciovec_t *iovs, size_t iovs_len, @@ -774,9 +736,7 @@ __wasi_errno_t wasmtime_ssp_fd_write( ) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_advise( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len, @@ -784,28 +744,22 @@ __wasi_errno_t wasmtime_ssp_fd_advise( ) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_allocate( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len ) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_create_directory( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const char *path, size_t path_len ) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_link( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct fd_prestats *prestats, -#endif __wasi_fd_t old_fd, __wasi_lookupflags_t old_flags, const char *old_path, @@ -816,9 +770,7 @@ __wasi_errno_t wasmtime_ssp_path_link( ) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_open( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t dirfd, __wasi_lookupflags_t dirflags, const char *path, @@ -831,9 +783,7 @@ __wasi_errno_t wasmtime_ssp_path_open( ) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_readdir( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, void *buf, size_t buf_len, @@ -842,9 +792,7 @@ __wasi_errno_t wasmtime_ssp_fd_readdir( ) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_readlink( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const char *path, size_t path_len, @@ -854,9 +802,7 @@ __wasi_errno_t wasmtime_ssp_path_readlink( ) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_rename( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t old_fd, const char *old_path, size_t old_path_len, @@ -866,17 +812,13 @@ __wasi_errno_t wasmtime_ssp_path_rename( ) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filestat_t *buf ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_set_times( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_timestamp_t st_atim, __wasi_timestamp_t st_mtim, @@ -884,17 +826,13 @@ __wasi_errno_t wasmtime_ssp_fd_filestat_set_times( ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_set_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_filesize_t st_size ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_filestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, @@ -903,9 +841,7 @@ __wasi_errno_t wasmtime_ssp_path_filestat_get( ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_filestat_set_times( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, @@ -916,10 +852,8 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times( ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_symlink( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct fd_prestats *prestats, -#endif const char *old_path, size_t old_path_len, __wasi_fd_t fd, @@ -928,27 +862,21 @@ __wasi_errno_t wasmtime_ssp_path_symlink( ) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_unlink_file( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const char *path, size_t path_len ) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_remove_directory( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, const char *path, size_t path_len ) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_poll_oneoff( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif const __wasi_subscription_t *in, __wasi_event_t *out, size_t nsubscriptions, @@ -962,50 +890,38 @@ __wasi_errno_t wasmtime_ssp_random_get( __wasi_errno_t wasi_ssp_sock_accept( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_local( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_remote( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_open( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype, __wasi_fd_t *sockfd ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_bind( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct addr_pool *addr_pool, -#endif __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_resolve( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, char **ns_lookup_list, -#endif const char *host, const char* service, __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info, __wasi_size_t addr_info_size, __wasi_size_t *max_info_size @@ -1013,88 +929,66 @@ wasi_ssp_sock_addr_resolve( __wasi_errno_t wasi_ssp_sock_connect( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct addr_pool *addr_pool, -#endif __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_size_t *size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, uint8_t *reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, uint8_t *reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_size_t *size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_size_t size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, uint8_t reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, uint8_t reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_size_t size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_listen( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t fd, __wasi_size_t backlog ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_recv( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, void *buf, size_t buf_len, @@ -1102,9 +996,7 @@ __wasi_errno_t wasmtime_ssp_sock_recv( ) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_recv_from( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, void *buf, size_t buf_len, @@ -1114,9 +1006,7 @@ __wasi_errno_t wasmtime_ssp_sock_recv_from( ) WASMTIME_SSP_SYSCALL_NAME(sock_recv_from) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_send( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, const void *buf, size_t buf_len, @@ -1124,9 +1014,7 @@ __wasi_errno_t wasmtime_ssp_sock_send( ) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_send_to( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, struct addr_pool *addr_pool, -#endif __wasi_fd_t sock, const void *buf, size_t buf_len, @@ -1136,317 +1024,239 @@ __wasi_errno_t wasmtime_ssp_sock_send_to( ) WASMTIME_SSP_SYSCALL_NAME(sock_send_to) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_shutdown( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock ) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_recv_timeout( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint64_t timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_recv_timeout( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint64_t *timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_send_timeout( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint64_t timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_send_timeout( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint64_t *timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, size_t bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, size_t *bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, size_t bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, size_t *bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_keep_alive( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_keep_alive) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_keep_alive( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_keep_alive) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_addr) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_addr) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_port) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_port) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_linger( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled, int linger_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_linger) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_linger( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled, int *linger_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_linger) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_broadcast( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_broadcast) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_broadcast( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_broadcast) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_no_delay( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_no_delay) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_no_delay( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_no_delay) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_quick_ack( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_quick_ack) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_quick_ack( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_quick_ack) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_idle( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint32_t time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_idle) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_idle( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint32_t *time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_idle) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_intvl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint32_t time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_intvl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_intvl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint32_t *time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_intvl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_fastopen_connect( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_fastopen_connect( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool ipv6, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_loop) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool ipv6, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_loop) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_add_membership) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_drop_membership) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_ttl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint8_t ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_ttl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint8_t *ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_ttl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint8_t ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_ttl( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, uint8_t *ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ipv6_only( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ipv6_only) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ipv6_only( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, -#endif __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ipv6_only) __attribute__((__warn_unused_result__)); diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 6fef381df..9fabd8830 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -55,13 +55,6 @@ static_assert(sizeof(struct iovec) == sizeof(__wasi_ciovec_t), "Size mismatch"); #endif -#if defined(WASMTIME_SSP_STATIC_CURFDS) -static __thread struct fd_table *curfds; -static __thread struct fd_prestats *prestats; -static __thread struct argv_environ_values *argv_environ; -static __thread struct addr_pool *addr_pool; -#endif - // Converts a POSIX error code to a CloudABI error code. static __wasi_errno_t convert_errno(int error) @@ -340,9 +333,6 @@ fd_prestats_init(struct fd_prestats *pt) pt->prestats = NULL; pt->size = 0; pt->used = 0; -#if defined(WASMTIME_SSP_STATIC_CURFDS) - prestats = pt; -#endif return true; } @@ -446,9 +436,6 @@ fd_table_init(struct fd_table *ft) ft->entries = NULL; ft->size = 0; ft->used = 0; -#if defined(WASMTIME_SSP_STATIC_CURFDS) - curfds = ft; -#endif return true; } @@ -786,11 +773,8 @@ fd_table_insert_fd(struct fd_table *ft, int in, __wasi_filetype_t type, } __wasi_errno_t -wasmtime_ssp_fd_prestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_prestats *prestats, -#endif - __wasi_fd_t fd, __wasi_prestat_t *buf) +wasmtime_ssp_fd_prestat_get(struct fd_prestats *prestats, __wasi_fd_t fd, + __wasi_prestat_t *buf) { rwlock_rdlock(&prestats->lock); struct fd_prestat *prestat; @@ -812,11 +796,8 @@ wasmtime_ssp_fd_prestat_get( } __wasi_errno_t -wasmtime_ssp_fd_prestat_dir_name( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_prestats *prestats, -#endif - __wasi_fd_t fd, char *path, size_t path_len) +wasmtime_ssp_fd_prestat_dir_name(struct fd_prestats *prestats, __wasi_fd_t fd, + char *path, size_t path_len) { rwlock_rdlock(&prestats->lock); struct fd_prestat *prestat; @@ -838,11 +819,8 @@ wasmtime_ssp_fd_prestat_dir_name( } __wasi_errno_t -wasmtime_ssp_fd_close( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct fd_prestats *prestats, -#endif - __wasi_fd_t fd) +wasmtime_ssp_fd_close(struct fd_table *curfds, struct fd_prestats *prestats, + __wasi_fd_t fd) { // Don't allow closing a pre-opened resource. // TODO: Eventually, we do want to permit this, once libpreopen in @@ -914,11 +892,7 @@ fd_object_get(struct fd_table *curfds, struct fd_object **fo, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_datasync( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd) +wasmtime_ssp_fd_datasync(struct fd_table *curfds, __wasi_fd_t fd) { struct fd_object *fo; __wasi_errno_t error = @@ -938,12 +912,9 @@ wasmtime_ssp_fd_datasync( } __wasi_errno_t -wasmtime_ssp_fd_pread( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const __wasi_iovec_t *iov, size_t iovcnt, - __wasi_filesize_t offset, size_t *nread) +wasmtime_ssp_fd_pread(struct fd_table *curfds, __wasi_fd_t fd, + const __wasi_iovec_t *iov, size_t iovcnt, + __wasi_filesize_t offset, size_t *nread) { if (iovcnt == 0) return __WASI_EINVAL; @@ -1012,12 +983,9 @@ wasmtime_ssp_fd_pread( } __wasi_errno_t -wasmtime_ssp_fd_pwrite( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const __wasi_ciovec_t *iov, size_t iovcnt, - __wasi_filesize_t offset, size_t *nwritten) +wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, + const __wasi_ciovec_t *iov, size_t iovcnt, + __wasi_filesize_t offset, size_t *nwritten) { if (iovcnt == 0) return __WASI_EINVAL; @@ -1066,11 +1034,8 @@ wasmtime_ssp_fd_pwrite( } __wasi_errno_t -wasmtime_ssp_fd_read( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const __wasi_iovec_t *iov, size_t iovcnt, size_t *nread) +wasmtime_ssp_fd_read(struct fd_table *curfds, __wasi_fd_t fd, + const __wasi_iovec_t *iov, size_t iovcnt, size_t *nread) { struct fd_object *fo; __wasi_errno_t error = @@ -1087,11 +1052,8 @@ wasmtime_ssp_fd_read( } __wasi_errno_t -wasmtime_ssp_fd_renumber( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct fd_prestats *prestats, -#endif - __wasi_fd_t from, __wasi_fd_t to) +wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats, + __wasi_fd_t from, __wasi_fd_t to) { // Don't allow renumbering over a pre-opened resource. // TODO: Eventually, we do want to permit this, once libpreopen in @@ -1141,12 +1103,9 @@ wasmtime_ssp_fd_renumber( } __wasi_errno_t -wasmtime_ssp_fd_seek( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filedelta_t offset, __wasi_whence_t whence, - __wasi_filesize_t *newoffset) +wasmtime_ssp_fd_seek(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filedelta_t offset, __wasi_whence_t whence, + __wasi_filesize_t *newoffset) { int nwhence; switch (whence) { @@ -1182,11 +1141,8 @@ wasmtime_ssp_fd_seek( } __wasi_errno_t -wasmtime_ssp_fd_tell( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filesize_t *newoffset) +wasmtime_ssp_fd_tell(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filesize_t *newoffset) { struct fd_object *fo; __wasi_errno_t error = @@ -1203,11 +1159,8 @@ wasmtime_ssp_fd_tell( } __wasi_errno_t -wasmtime_ssp_fd_fdstat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_fdstat_t *buf) +wasmtime_ssp_fd_fdstat_get(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_fdstat_t *buf) { struct fd_table *ft = curfds; rwlock_rdlock(&ft->lock); @@ -1255,11 +1208,8 @@ wasmtime_ssp_fd_fdstat_get( } __wasi_errno_t -wasmtime_ssp_fd_fdstat_set_flags( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_fdflags_t fs_flags) +wasmtime_ssp_fd_fdstat_set_flags(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_fdflags_t fs_flags) { int noflags = 0; if ((fs_flags & __WASI_FDFLAG_APPEND) != 0) @@ -1295,12 +1245,9 @@ wasmtime_ssp_fd_fdstat_set_flags( } __wasi_errno_t -wasmtime_ssp_fd_fdstat_set_rights( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_rights_t fs_rights_base, - __wasi_rights_t fs_rights_inheriting) +wasmtime_ssp_fd_fdstat_set_rights(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_rights_t fs_rights_base, + __wasi_rights_t fs_rights_inheriting) { struct fd_table *ft = curfds; rwlock_wrlock(&ft->lock); @@ -1320,11 +1267,7 @@ wasmtime_ssp_fd_fdstat_set_rights( } __wasi_errno_t -wasmtime_ssp_fd_sync( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd) +wasmtime_ssp_fd_sync(struct fd_table *curfds, __wasi_fd_t fd) { struct fd_object *fo; __wasi_errno_t error = @@ -1340,11 +1283,9 @@ wasmtime_ssp_fd_sync( } __wasi_errno_t -wasmtime_ssp_fd_write( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const __wasi_ciovec_t *iov, size_t iovcnt, size_t *nwritten) +wasmtime_ssp_fd_write(struct fd_table *curfds, __wasi_fd_t fd, + const __wasi_ciovec_t *iov, size_t iovcnt, + size_t *nwritten) { struct fd_object *fo; __wasi_errno_t error = @@ -1383,12 +1324,9 @@ wasmtime_ssp_fd_write( } __wasi_errno_t -wasmtime_ssp_fd_advise( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len, - __wasi_advice_t advice) +wasmtime_ssp_fd_advise(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filesize_t offset, __wasi_filesize_t len, + __wasi_advice_t advice) { #ifdef POSIX_FADV_NORMAL int nadvice; @@ -1452,11 +1390,8 @@ wasmtime_ssp_fd_advise( } __wasi_errno_t -wasmtime_ssp_fd_allocate( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len) +wasmtime_ssp_fd_allocate(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filesize_t offset, __wasi_filesize_t len) { struct fd_object *fo; __wasi_errno_t error = @@ -1793,11 +1728,8 @@ path_put(struct path_access *pa) UNLOCKS(pa->fd_object->refcount) } __wasi_errno_t -wasmtime_ssp_path_create_directory( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const char *path, size_t pathlen) +wasmtime_ssp_path_create_directory(struct fd_table *curfds, __wasi_fd_t fd, + const char *path, size_t pathlen) { struct path_access pa; __wasi_errno_t error = @@ -1841,13 +1773,11 @@ validate_path(const char *path, struct fd_prestats *pt) } __wasi_errno_t -wasmtime_ssp_path_link( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct fd_prestats *prestats, -#endif - __wasi_fd_t old_fd, __wasi_lookupflags_t old_flags, const char *old_path, - size_t old_path_len, __wasi_fd_t new_fd, const char *new_path, - size_t new_path_len) +wasmtime_ssp_path_link(struct fd_table *curfds, struct fd_prestats *prestats, + __wasi_fd_t old_fd, __wasi_lookupflags_t old_flags, + const char *old_path, size_t old_path_len, + __wasi_fd_t new_fd, const char *new_path, + size_t new_path_len) { struct path_access old_pa; __wasi_errno_t error = @@ -1900,14 +1830,12 @@ wasmtime_ssp_path_link( } __wasi_errno_t -wasmtime_ssp_path_open( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t dirfd, __wasi_lookupflags_t dirflags, const char *path, - size_t pathlen, __wasi_oflags_t oflags, __wasi_rights_t fs_rights_base, - __wasi_rights_t fs_rights_inheriting, __wasi_fdflags_t fs_flags, - __wasi_fd_t *fd) +wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd, + __wasi_lookupflags_t dirflags, const char *path, + size_t pathlen, __wasi_oflags_t oflags, + __wasi_rights_t fs_rights_base, + __wasi_rights_t fs_rights_inheriting, + __wasi_fdflags_t fs_flags, __wasi_fd_t *fd) { // Rights that should be installed on the new file descriptor. __wasi_rights_t rights_base = fs_rights_base; @@ -2054,12 +1982,9 @@ fd_readdir_put(void *buf, size_t bufsize, size_t *bufused, const void *elem, } __wasi_errno_t -wasmtime_ssp_fd_readdir( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, void *buf, size_t nbyte, __wasi_dircookie_t cookie, - size_t *bufused) +wasmtime_ssp_fd_readdir(struct fd_table *curfds, __wasi_fd_t fd, void *buf, + size_t nbyte, __wasi_dircookie_t cookie, + size_t *bufused) { struct fd_object *fo; __wasi_errno_t error = @@ -2153,12 +2078,9 @@ wasmtime_ssp_fd_readdir( } __wasi_errno_t -wasmtime_ssp_path_readlink( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const char *path, size_t pathlen, char *buf, size_t bufsize, - size_t *bufused) +wasmtime_ssp_path_readlink(struct fd_table *curfds, __wasi_fd_t fd, + const char *path, size_t pathlen, char *buf, + size_t bufsize, size_t *bufused) { struct path_access pa; __wasi_errno_t error = path_get_nofollow( @@ -2179,12 +2101,10 @@ wasmtime_ssp_path_readlink( } __wasi_errno_t -wasmtime_ssp_path_rename( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t old_fd, const char *old_path, size_t old_path_len, - __wasi_fd_t new_fd, const char *new_path, size_t new_path_len) +wasmtime_ssp_path_rename(struct fd_table *curfds, __wasi_fd_t old_fd, + const char *old_path, size_t old_path_len, + __wasi_fd_t new_fd, const char *new_path, + size_t new_path_len) { struct path_access old_pa; __wasi_errno_t error = @@ -2226,11 +2146,8 @@ convert_stat(const struct stat *in, __wasi_filestat_t *out) } __wasi_errno_t -wasmtime_ssp_fd_filestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filestat_t *buf) +wasmtime_ssp_fd_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filestat_t *buf) { struct fd_object *fo; __wasi_errno_t error = @@ -2299,11 +2216,8 @@ convert_utimens_arguments(__wasi_timestamp_t st_atim, } __wasi_errno_t -wasmtime_ssp_fd_filestat_set_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_filesize_t st_size) +wasmtime_ssp_fd_filestat_set_size(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_filesize_t st_size) { struct fd_object *fo; __wasi_errno_t error = @@ -2319,12 +2233,10 @@ wasmtime_ssp_fd_filestat_set_size( } __wasi_errno_t -wasmtime_ssp_fd_filestat_set_times( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_timestamp_t st_atim, __wasi_timestamp_t st_mtim, - __wasi_fstflags_t fstflags) +wasmtime_ssp_fd_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_timestamp_t st_atim, + __wasi_timestamp_t st_mtim, + __wasi_fstflags_t fstflags) { if ((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW @@ -2349,12 +2261,9 @@ wasmtime_ssp_fd_filestat_set_times( } __wasi_errno_t -wasmtime_ssp_path_filestat_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, - size_t pathlen, __wasi_filestat_t *buf) +wasmtime_ssp_path_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_lookupflags_t flags, const char *path, + size_t pathlen, __wasi_filestat_t *buf) { struct path_access pa; __wasi_errno_t error = path_get(curfds, &pa, fd, flags, path, pathlen, @@ -2389,13 +2298,12 @@ wasmtime_ssp_path_filestat_get( } __wasi_errno_t -wasmtime_ssp_path_filestat_set_times( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, - size_t pathlen, __wasi_timestamp_t st_atim, __wasi_timestamp_t st_mtim, - __wasi_fstflags_t fstflags) +wasmtime_ssp_path_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_lookupflags_t flags, + const char *path, size_t pathlen, + __wasi_timestamp_t st_atim, + __wasi_timestamp_t st_mtim, + __wasi_fstflags_t fstflags) { if (((fstflags & ~(__WASI_FILESTAT_SET_ATIM | __WASI_FILESTAT_SET_ATIM_NOW @@ -2428,12 +2336,10 @@ wasmtime_ssp_path_filestat_set_times( } __wasi_errno_t -wasmtime_ssp_path_symlink( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct fd_prestats *prestats, -#endif - const char *old_path, size_t old_path_len, __wasi_fd_t fd, - const char *new_path, size_t new_path_len) +wasmtime_ssp_path_symlink(struct fd_table *curfds, struct fd_prestats *prestats, + const char *old_path, size_t old_path_len, + __wasi_fd_t fd, const char *new_path, + size_t new_path_len) { char *target = str_nullterminate(old_path, old_path_len); if (target == NULL) @@ -2465,11 +2371,8 @@ wasmtime_ssp_path_symlink( } __wasi_errno_t -wasmtime_ssp_path_unlink_file( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const char *path, size_t pathlen) +wasmtime_ssp_path_unlink_file(struct fd_table *curfds, __wasi_fd_t fd, + const char *path, size_t pathlen) { struct path_access pa; __wasi_errno_t error = path_get_nofollow( @@ -2502,11 +2405,8 @@ wasmtime_ssp_path_unlink_file( } __wasi_errno_t -wasmtime_ssp_path_remove_directory( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, const char *path, size_t pathlen) +wasmtime_ssp_path_remove_directory(struct fd_table *curfds, __wasi_fd_t fd, + const char *path, size_t pathlen) { struct path_access pa; __wasi_errno_t error = @@ -2531,12 +2431,10 @@ wasmtime_ssp_path_remove_directory( } __wasi_errno_t -wasmtime_ssp_poll_oneoff( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - const __wasi_subscription_t *in, __wasi_event_t *out, size_t nsubscriptions, - size_t *nevents) NO_LOCK_ANALYSIS +wasmtime_ssp_poll_oneoff(struct fd_table *curfds, + const __wasi_subscription_t *in, __wasi_event_t *out, + size_t nsubscriptions, + size_t *nevents) NO_LOCK_ANALYSIS { // Sleeping. if (nsubscriptions == 1 && in[0].u.type == __WASI_EVENTTYPE_CLOCK) { @@ -2795,11 +2693,8 @@ wasmtime_ssp_random_get(void *buf, size_t nbyte) } __wasi_errno_t -wasi_ssp_sock_accept( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new) +wasi_ssp_sock_accept(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_fdflags_t flags, __wasi_fd_t *fd_new) { __wasi_filetype_t wasi_type; __wasi_rights_t max_base, max_inheriting; @@ -2843,11 +2738,8 @@ fail: } __wasi_errno_t -wasi_ssp_sock_addr_local( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_addr_local(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_addr_t *addr) { struct fd_object *fo; bh_sockaddr_t bh_addr; @@ -2870,11 +2762,8 @@ wasi_ssp_sock_addr_local( } __wasi_errno_t -wasi_ssp_sock_addr_remote( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_addr_remote(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_addr_t *addr) { struct fd_object *fo; bh_sockaddr_t bh_addr; @@ -2926,11 +2815,8 @@ wasi_addr_to_string(const __wasi_addr_t *addr, char *buf, size_t buflen) } __wasi_errno_t -wasi_ssp_sock_bind( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct addr_pool *addr_pool, -#endif - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_bind(struct fd_table *curfds, struct addr_pool *addr_pool, + __wasi_fd_t fd, __wasi_addr_t *addr) { char buf[48] = { 0 }; struct fd_object *fo; @@ -2960,13 +2846,12 @@ wasi_ssp_sock_bind( } __wasi_errno_t -wasi_ssp_sock_addr_resolve( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, char **ns_lookup_list, -#endif - const char *host, const char *service, __wasi_addr_info_hints_t *hints, - __wasi_addr_info_t *addr_info, __wasi_size_t addr_info_size, - __wasi_size_t *max_info_size) +wasi_ssp_sock_addr_resolve(struct fd_table *curfds, char **ns_lookup_list, + const char *host, const char *service, + __wasi_addr_info_hints_t *hints, + __wasi_addr_info_t *addr_info, + __wasi_size_t addr_info_size, + __wasi_size_t *max_info_size) { bh_addr_info_t *wamr_addr_info = wasm_runtime_malloc(addr_info_size * sizeof(bh_addr_info_t)); @@ -3013,11 +2898,8 @@ wasi_ssp_sock_addr_resolve( } __wasi_errno_t -wasi_ssp_sock_connect( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct addr_pool *addr_pool, -#endif - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_connect(struct fd_table *curfds, struct addr_pool *addr_pool, + __wasi_fd_t fd, __wasi_addr_t *addr) { char buf[48] = { 0 }; struct fd_object *fo; @@ -3048,11 +2930,8 @@ wasi_ssp_sock_connect( } __wasi_errno_t -wasi_ssp_sock_get_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_size_t *size) +wasi_ssp_sock_get_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_size_t *size) { struct fd_object *fo; int ret; @@ -3075,11 +2954,8 @@ wasi_ssp_sock_get_recv_buf_size( } __wasi_errno_t -wasi_ssp_sock_get_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, uint8_t *reuse) +wasi_ssp_sock_get_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, + uint8_t *reuse) { struct fd_object *fo; @@ -3103,11 +2979,8 @@ wasi_ssp_sock_get_reuse_addr( } __wasi_errno_t -wasi_ssp_sock_get_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, uint8_t *reuse) +wasi_ssp_sock_get_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, + uint8_t *reuse) { struct fd_object *fo; int ret; @@ -3137,11 +3010,8 @@ wasi_ssp_sock_get_reuse_port( } __wasi_errno_t -wasi_ssp_sock_get_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_size_t *size) +wasi_ssp_sock_get_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_size_t *size) { struct fd_object *fo; int ret; @@ -3164,11 +3034,8 @@ wasi_ssp_sock_get_send_buf_size( } __wasi_errno_t -wasi_ssp_sock_listen( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_size_t backlog) +wasi_ssp_sock_listen(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_size_t backlog) { struct fd_object *fo; int ret; @@ -3187,12 +3054,9 @@ wasi_ssp_sock_listen( } __wasi_errno_t -wasi_ssp_sock_open( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype, - __wasi_fd_t *sockfd) +wasi_ssp_sock_open(struct fd_table *curfds, __wasi_fd_t poolfd, + __wasi_address_family_t af, __wasi_sock_type_t socktype, + __wasi_fd_t *sockfd) { bh_socket_t sock; bool is_tcp = SOCKET_DGRAM == socktype ? false : true; @@ -3234,11 +3098,8 @@ wasi_ssp_sock_open( } __wasi_errno_t -wasi_ssp_sock_set_recv_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_size_t size) +wasi_ssp_sock_set_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_size_t size) { struct fd_object *fo; int ret; @@ -3259,11 +3120,8 @@ wasi_ssp_sock_set_recv_buf_size( } __wasi_errno_t -wasi_ssp_sock_set_reuse_addr( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, uint8_t reuse) +wasi_ssp_sock_set_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, + uint8_t reuse) { struct fd_object *fo; int ret; @@ -3284,11 +3142,8 @@ wasi_ssp_sock_set_reuse_addr( } __wasi_errno_t -wasi_ssp_sock_set_reuse_port( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, uint8_t reuse) +wasi_ssp_sock_set_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, + uint8_t reuse) { struct fd_object *fo; int ret; @@ -3315,11 +3170,8 @@ wasi_ssp_sock_set_reuse_port( } __wasi_errno_t -wasi_ssp_sock_set_send_buf_size( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t fd, __wasi_size_t size) +wasi_ssp_sock_set_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, + __wasi_size_t size) { struct fd_object *fo; int ret; @@ -3341,11 +3193,8 @@ wasi_ssp_sock_set_send_buf_size( } __wasi_errno_t -wasmtime_ssp_sock_recv( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, void *buf, size_t buf_len, size_t *recv_len) +wasmtime_ssp_sock_recv(struct fd_table *curfds, __wasi_fd_t sock, void *buf, + size_t buf_len, size_t *recv_len) { __wasi_addr_t src_addr; @@ -3354,12 +3203,10 @@ wasmtime_ssp_sock_recv( } __wasi_errno_t -wasmtime_ssp_sock_recv_from( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, void *buf, size_t buf_len, __wasi_riflags_t ri_flags, - __wasi_addr_t *src_addr, size_t *recv_len) +wasmtime_ssp_sock_recv_from(struct fd_table *curfds, __wasi_fd_t sock, + void *buf, size_t buf_len, + __wasi_riflags_t ri_flags, __wasi_addr_t *src_addr, + size_t *recv_len) { struct fd_object *fo; __wasi_errno_t error; @@ -3384,11 +3231,8 @@ wasmtime_ssp_sock_recv_from( } __wasi_errno_t -wasmtime_ssp_sock_send( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, const void *buf, size_t buf_len, size_t *sent_len) +wasmtime_ssp_sock_send(struct fd_table *curfds, __wasi_fd_t sock, + const void *buf, size_t buf_len, size_t *sent_len) { struct fd_object *fo; __wasi_errno_t error; @@ -3410,12 +3254,10 @@ wasmtime_ssp_sock_send( } __wasi_errno_t -wasmtime_ssp_sock_send_to( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, struct addr_pool *addr_pool, -#endif - __wasi_fd_t sock, const void *buf, size_t buf_len, - __wasi_siflags_t si_flags, const __wasi_addr_t *dest_addr, size_t *sent_len) +wasmtime_ssp_sock_send_to(struct fd_table *curfds, struct addr_pool *addr_pool, + __wasi_fd_t sock, const void *buf, size_t buf_len, + __wasi_siflags_t si_flags, + const __wasi_addr_t *dest_addr, size_t *sent_len) { char addr_buf[48] = { 0 }; struct fd_object *fo; @@ -3449,11 +3291,7 @@ wasmtime_ssp_sock_send_to( } __wasi_errno_t -wasmtime_ssp_sock_shutdown( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock) +wasmtime_ssp_sock_shutdown(struct fd_table *curfds, __wasi_fd_t sock) { struct fd_object *fo; __wasi_errno_t error; @@ -3480,11 +3318,8 @@ wasmtime_ssp_sched_yield(void) } __wasi_errno_t -wasmtime_ssp_args_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct argv_environ_values *argv_environ, -#endif - char **argv, char *argv_buf) +wasmtime_ssp_args_get(struct argv_environ_values *argv_environ, char **argv, + char *argv_buf) { for (size_t i = 0; i < argv_environ->argc; ++i) { argv[i] = @@ -3497,11 +3332,8 @@ wasmtime_ssp_args_get( } __wasi_errno_t -wasmtime_ssp_args_sizes_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct argv_environ_values *argv_environ, -#endif - size_t *argc, size_t *argv_buf_size) +wasmtime_ssp_args_sizes_get(struct argv_environ_values *argv_environ, + size_t *argc, size_t *argv_buf_size) { *argc = argv_environ->argc; *argv_buf_size = argv_environ->argv_buf_size; @@ -3509,11 +3341,8 @@ wasmtime_ssp_args_sizes_get( } __wasi_errno_t -wasmtime_ssp_environ_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct argv_environ_values *argv_environ, -#endif - char **environ, char *environ_buf) +wasmtime_ssp_environ_get(struct argv_environ_values *argv_environ, + char **environ, char *environ_buf) { for (size_t i = 0; i < argv_environ->environ_count; ++i) { environ[i] = @@ -3528,11 +3357,8 @@ wasmtime_ssp_environ_get( } __wasi_errno_t -wasmtime_ssp_environ_sizes_get( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct argv_environ_values *argv_environ, -#endif - size_t *environ_count, size_t *environ_buf_size) +wasmtime_ssp_environ_sizes_get(struct argv_environ_values *argv_environ, + size_t *environ_count, size_t *environ_buf_size) { *environ_count = argv_environ->environ_count; *environ_buf_size = argv_environ->environ_buf_size; @@ -3757,11 +3583,7 @@ addr_pool_destroy(struct addr_pool *addr_pool) } } -#ifndef WASMTIME_SSP_STATIC_CURFDS #define WASMTIME_SSP_PASSTHROUGH_FD_TABLE struct fd_table *curfds, -#else -#define WASMTIME_SSP_PASSTHROUGH_FD_TABLE -#endif // Defines a function that passes through the socket option to the OS // implementation @@ -3820,11 +3642,8 @@ WASMTIME_SSP_PASSTHROUGH_SOCKET_OPTION(get_ipv6_only, bool *) #undef WASMTIME_SSP_PASSTHROUGH_SOCKET_OPTION __wasi_errno_t -wasmtime_ssp_sock_set_linger( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, bool is_enabled, int linger_s) +wasmtime_ssp_sock_set_linger(struct fd_table *curfds, __wasi_fd_t sock, + bool is_enabled, int linger_s) { struct fd_object *fo; __wasi_errno_t error; @@ -3841,11 +3660,8 @@ wasmtime_ssp_sock_set_linger( } __wasi_errno_t -wasmtime_ssp_sock_get_linger( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, bool *is_enabled, int *linger_s) +wasmtime_ssp_sock_get_linger(struct fd_table *curfds, __wasi_fd_t sock, + bool *is_enabled, int *linger_s) { struct fd_object *fo; __wasi_errno_t error; @@ -3863,11 +3679,10 @@ wasmtime_ssp_sock_get_linger( } __wasi_errno_t -wasmtime_ssp_sock_set_ip_add_membership( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface) +wasmtime_ssp_sock_set_ip_add_membership(struct fd_table *curfds, + __wasi_fd_t sock, + __wasi_addr_ip_t *imr_multiaddr, + uint32_t imr_interface) { struct fd_object *fo; __wasi_errno_t error; @@ -3889,11 +3704,10 @@ wasmtime_ssp_sock_set_ip_add_membership( } __wasi_errno_t -wasmtime_ssp_sock_set_ip_drop_membership( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface) +wasmtime_ssp_sock_set_ip_drop_membership(struct fd_table *curfds, + __wasi_fd_t sock, + __wasi_addr_ip_t *imr_multiaddr, + uint32_t imr_interface) { struct fd_object *fo; __wasi_errno_t error; @@ -3915,11 +3729,9 @@ wasmtime_ssp_sock_set_ip_drop_membership( } __wasi_errno_t -wasmtime_ssp_sock_set_ip_multicast_loop( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, bool ipv6, bool is_enabled) +wasmtime_ssp_sock_set_ip_multicast_loop(struct fd_table *curfds, + __wasi_fd_t sock, bool ipv6, + bool is_enabled) { struct fd_object *fo; __wasi_errno_t error; @@ -3936,11 +3748,9 @@ wasmtime_ssp_sock_set_ip_multicast_loop( } __wasi_errno_t -wasmtime_ssp_sock_get_ip_multicast_loop( -#if !defined(WASMTIME_SSP_STATIC_CURFDS) - struct fd_table *curfds, -#endif - __wasi_fd_t sock, bool ipv6, bool *is_enabled) +wasmtime_ssp_sock_get_ip_multicast_loop(struct fd_table *curfds, + __wasi_fd_t sock, bool ipv6, + bool *is_enabled) { struct fd_object *fo; __wasi_errno_t error; From af2f3c8759b549db67858a9537b98ad15a148594 Mon Sep 17 00:00:00 2001 From: Cengizhan Pasaoglu Date: Thu, 7 Sep 2023 09:29:52 +0300 Subject: [PATCH 13/58] Fix typo for IP address buffer (#2532) --- .../sandboxed-system-primitives/src/posix.c | 48 +++++++++---------- .../platform/common/posix/posix_socket.c | 16 +++---- core/shared/platform/esp-idf/espidf_socket.c | 2 +- .../platform/include/platform_api_extension.h | 2 +- core/shared/platform/linux-sgx/sgx_socket.c | 4 +- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 9fabd8830..2af2f2d02 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -221,22 +221,22 @@ wasi_addr_to_bh_sockaddr(const __wasi_addr_t *wasi_addr, bh_sockaddr_t *sockaddr) { if (wasi_addr->kind == IPv4) { - sockaddr->addr_bufer.ipv4 = (wasi_addr->addr.ip4.addr.n0 << 24) - | (wasi_addr->addr.ip4.addr.n1 << 16) - | (wasi_addr->addr.ip4.addr.n2 << 8) - | wasi_addr->addr.ip4.addr.n3; + sockaddr->addr_buffer.ipv4 = (wasi_addr->addr.ip4.addr.n0 << 24) + | (wasi_addr->addr.ip4.addr.n1 << 16) + | (wasi_addr->addr.ip4.addr.n2 << 8) + | wasi_addr->addr.ip4.addr.n3; sockaddr->is_ipv4 = true; sockaddr->port = wasi_addr->addr.ip4.port; } else { - sockaddr->addr_bufer.ipv6[0] = wasi_addr->addr.ip6.addr.n0; - sockaddr->addr_bufer.ipv6[1] = wasi_addr->addr.ip6.addr.n1; - sockaddr->addr_bufer.ipv6[2] = wasi_addr->addr.ip6.addr.n2; - sockaddr->addr_bufer.ipv6[3] = wasi_addr->addr.ip6.addr.n3; - sockaddr->addr_bufer.ipv6[4] = wasi_addr->addr.ip6.addr.h0; - sockaddr->addr_bufer.ipv6[5] = wasi_addr->addr.ip6.addr.h1; - sockaddr->addr_bufer.ipv6[6] = wasi_addr->addr.ip6.addr.h2; - sockaddr->addr_bufer.ipv6[7] = wasi_addr->addr.ip6.addr.h3; + sockaddr->addr_buffer.ipv6[0] = wasi_addr->addr.ip6.addr.n0; + sockaddr->addr_buffer.ipv6[1] = wasi_addr->addr.ip6.addr.n1; + sockaddr->addr_buffer.ipv6[2] = wasi_addr->addr.ip6.addr.n2; + sockaddr->addr_buffer.ipv6[3] = wasi_addr->addr.ip6.addr.n3; + sockaddr->addr_buffer.ipv6[4] = wasi_addr->addr.ip6.addr.h0; + sockaddr->addr_buffer.ipv6[5] = wasi_addr->addr.ip6.addr.h1; + sockaddr->addr_buffer.ipv6[6] = wasi_addr->addr.ip6.addr.h2; + sockaddr->addr_buffer.ipv6[7] = wasi_addr->addr.ip6.addr.h3; sockaddr->is_ipv4 = false; sockaddr->port = wasi_addr->addr.ip6.port; } @@ -251,24 +251,24 @@ bh_sockaddr_to_wasi_addr(const bh_sockaddr_t *sockaddr, wasi_addr->kind = IPv4; wasi_addr->addr.ip4.port = sockaddr->port; wasi_addr->addr.ip4.addr.n0 = - (sockaddr->addr_bufer.ipv4 & 0xFF000000) >> 24; + (sockaddr->addr_buffer.ipv4 & 0xFF000000) >> 24; wasi_addr->addr.ip4.addr.n1 = - (sockaddr->addr_bufer.ipv4 & 0x00FF0000) >> 16; + (sockaddr->addr_buffer.ipv4 & 0x00FF0000) >> 16; wasi_addr->addr.ip4.addr.n2 = - (sockaddr->addr_bufer.ipv4 & 0x0000FF00) >> 8; - wasi_addr->addr.ip4.addr.n3 = (sockaddr->addr_bufer.ipv4 & 0x000000FF); + (sockaddr->addr_buffer.ipv4 & 0x0000FF00) >> 8; + wasi_addr->addr.ip4.addr.n3 = (sockaddr->addr_buffer.ipv4 & 0x000000FF); } else { wasi_addr->kind = IPv6; wasi_addr->addr.ip6.port = sockaddr->port; - wasi_addr->addr.ip6.addr.n0 = sockaddr->addr_bufer.ipv6[0]; - wasi_addr->addr.ip6.addr.n1 = sockaddr->addr_bufer.ipv6[1]; - wasi_addr->addr.ip6.addr.n2 = sockaddr->addr_bufer.ipv6[2]; - wasi_addr->addr.ip6.addr.n3 = sockaddr->addr_bufer.ipv6[3]; - wasi_addr->addr.ip6.addr.h0 = sockaddr->addr_bufer.ipv6[4]; - wasi_addr->addr.ip6.addr.h1 = sockaddr->addr_bufer.ipv6[5]; - wasi_addr->addr.ip6.addr.h2 = sockaddr->addr_bufer.ipv6[6]; - wasi_addr->addr.ip6.addr.h3 = sockaddr->addr_bufer.ipv6[7]; + wasi_addr->addr.ip6.addr.n0 = sockaddr->addr_buffer.ipv6[0]; + wasi_addr->addr.ip6.addr.n1 = sockaddr->addr_buffer.ipv6[1]; + wasi_addr->addr.ip6.addr.n2 = sockaddr->addr_buffer.ipv6[2]; + wasi_addr->addr.ip6.addr.n3 = sockaddr->addr_buffer.ipv6[3]; + wasi_addr->addr.ip6.addr.h0 = sockaddr->addr_buffer.ipv6[4]; + wasi_addr->addr.ip6.addr.h1 = sockaddr->addr_buffer.ipv6[5]; + wasi_addr->addr.ip6.addr.h2 = sockaddr->addr_buffer.ipv6[6]; + wasi_addr->addr.ip6.addr.h3 = sockaddr->addr_buffer.ipv6[7]; } } diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index d0a232bc5..9f5538b5c 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -53,7 +53,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr; bh_sockaddr->port = ntohs(addr->sin_port); - bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr); + bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr); bh_sockaddr->is_ipv4 = true; return BHT_OK; } @@ -65,12 +65,12 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, bh_sockaddr->port = ntohs(addr->sin6_port); - for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6) - / sizeof(bh_sockaddr->addr_bufer.ipv6[0]); + for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6) + / sizeof(bh_sockaddr->addr_buffer.ipv6[0]); i++) { uint16 part_addr = addr->sin6_addr.s6_addr[i * 2] | (addr->sin6_addr.s6_addr[i * 2 + 1] << 8); - bh_sockaddr->addr_bufer.ipv6[i] = ntohs(part_addr); + bh_sockaddr->addr_buffer.ipv6[i] = ntohs(part_addr); } bh_sockaddr->is_ipv4 = false; @@ -91,7 +91,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr, struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr; addr->sin_port = htons(bh_sockaddr->port); addr->sin_family = AF_INET; - addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4); + addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4); *socklen = sizeof(*addr); } #ifdef IPPROTO_IPV6 @@ -101,10 +101,10 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr, addr->sin6_port = htons(bh_sockaddr->port); addr->sin6_family = AF_INET6; - for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6) - / sizeof(bh_sockaddr->addr_bufer.ipv6[0]); + for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6) + / sizeof(bh_sockaddr->addr_buffer.ipv6[0]); i++) { - uint16 part_addr = htons(bh_sockaddr->addr_bufer.ipv6[i]); + uint16 part_addr = htons(bh_sockaddr->addr_buffer.ipv6[i]); addr->sin6_addr.s6_addr[i * 2] = 0xff & part_addr; addr->sin6_addr.s6_addr[i * 2 + 1] = (0xff00 & part_addr) >> 8; } diff --git a/core/shared/platform/esp-idf/espidf_socket.c b/core/shared/platform/esp-idf/espidf_socket.c index 9f441b712..83a24f435 100644 --- a/core/shared/platform/esp-idf/espidf_socket.c +++ b/core/shared/platform/esp-idf/espidf_socket.c @@ -30,7 +30,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen, assert(socklen >= sizeof(struct sockaddr_in)); bh_sockaddr->port = ntohs(addr->sin_port); - bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr); + bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr); bh_sockaddr->is_ipv4 = true; return BHT_OK; } diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 7029bb8d7..5b7b556e0 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -342,7 +342,7 @@ typedef union { } bh_ip_addr_buffer_t; typedef struct { - bh_ip_addr_buffer_t addr_bufer; + bh_ip_addr_buffer_t addr_buffer; uint16 port; bool is_ipv4; } bh_sockaddr_t; diff --git a/core/shared/platform/linux-sgx/sgx_socket.c b/core/shared/platform/linux-sgx/sgx_socket.c index afb6d6014..4d3f9a6b5 100644 --- a/core/shared/platform/linux-sgx/sgx_socket.c +++ b/core/shared/platform/linux-sgx/sgx_socket.c @@ -261,7 +261,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen, assert(socklen >= sizeof(struct sockaddr_in)); bh_sockaddr->port = ntohs(addr->sin_port); - bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr); + bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr); bh_sockaddr->is_ipv4 = true; return BHT_OK; } @@ -279,7 +279,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr, struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr; addr->sin_port = htons(bh_sockaddr->port); addr->sin_family = AF_INET; - addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4); + addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4); *socklen = sizeof(*addr); return BHT_OK; } From 6c846acc59b281b23e4cf81322e9bd39c48c9779 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 7 Sep 2023 15:54:11 +0900 Subject: [PATCH 14/58] Implement module instance context APIs (#2436) Introduce module instance context APIs which can set one or more contexts created by the embedder for a wasm module instance: ```C wasm_runtime_create_context_key wasm_runtime_destroy_context_key wasm_runtime_set_context wasm_runtime_set_context_spread wasm_runtime_get_context ``` And make libc-wasi use it and set wasi context as the first context bound to the wasm module instance. Also add samples. Refer to https://github.com/bytecodealliance/wasm-micro-runtime/issues/2460. --- build-scripts/config_common.cmake | 4 + build-scripts/runtime_lib.cmake | 2 + core/config.h | 5 + core/iwasm/aot/aot_runtime.c | 4 +- core/iwasm/common/wasm_native.c | 172 ++++++++++++++++++ core/iwasm/common/wasm_native.h | 30 +++ core/iwasm/common/wasm_runtime_common.c | 55 +++--- core/iwasm/common/wasm_runtime_common.h | 20 ++ core/iwasm/include/wasm_export.h | 68 +++++++ core/iwasm/interpreter/wasm_runtime.c | 4 +- core/iwasm/interpreter/wasm_runtime.h | 9 +- .../lib-pthread/lib_pthread_wrapper.c | 9 +- .../lib_wasi_threads_wrapper.c | 9 +- .../libraries/thread-mgr/thread_manager.c | 50 ++++- .../libraries/thread-mgr/thread_manager.h | 4 + product-mini/platforms/nuttx/wamr.mk | 8 + samples/inst-context-threads/.gitignore | 1 + samples/inst-context-threads/CMakeLists.txt | 92 ++++++++++ samples/inst-context-threads/README.md | 4 + samples/inst-context-threads/build.sh | 61 +++++++ samples/inst-context-threads/run.sh | 3 + samples/inst-context-threads/src/main.c | 151 +++++++++++++++ samples/inst-context-threads/src/my_context.h | 11 ++ .../inst-context-threads/src/native_impl.c | 32 ++++ .../inst-context-threads/wasm-apps/testapp.c | 65 +++++++ samples/inst-context/.gitignore | 1 + samples/inst-context/CMakeLists.txt | 91 +++++++++ samples/inst-context/README.md | 4 + samples/inst-context/build.sh | 63 +++++++ samples/inst-context/run.sh | 3 + samples/inst-context/src/main.c | 166 +++++++++++++++++ samples/inst-context/src/my_context.h | 10 + samples/inst-context/src/native_impl.c | 15 ++ samples/inst-context/wasm-apps/testapp.c | 19 ++ wamr-compiler/CMakeLists.txt | 1 + 35 files changed, 1190 insertions(+), 56 deletions(-) create mode 100644 samples/inst-context-threads/.gitignore create mode 100644 samples/inst-context-threads/CMakeLists.txt create mode 100644 samples/inst-context-threads/README.md create mode 100755 samples/inst-context-threads/build.sh create mode 100755 samples/inst-context-threads/run.sh create mode 100644 samples/inst-context-threads/src/main.c create mode 100644 samples/inst-context-threads/src/my_context.h create mode 100644 samples/inst-context-threads/src/native_impl.c create mode 100644 samples/inst-context-threads/wasm-apps/testapp.c create mode 100644 samples/inst-context/.gitignore create mode 100644 samples/inst-context/CMakeLists.txt create mode 100644 samples/inst-context/README.md create mode 100755 samples/inst-context/build.sh create mode 100755 samples/inst-context/run.sh create mode 100644 samples/inst-context/src/main.c create mode 100644 samples/inst-context/src/my_context.h create mode 100644 samples/inst-context/src/native_impl.c create mode 100644 samples/inst-context/wasm-apps/testapp.c diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 2751341e4..0e27e0c09 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -378,6 +378,10 @@ if (WAMR_BUILD_WASM_CACHE EQUAL 1) add_definitions (-DWASM_ENABLE_WASM_CACHE=1) message (" Wasm files cache enabled") endif () +if (WAMR_BUILD_MODULE_INST_CONTEXT EQUAL 1) + add_definitions (-DWASM_ENABLE_MODULE_INST_CONTEXT=1) + message (" Module instance context enabled") +endif () if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1) add_definitions (-DWASM_ENABLE_GC_VERIFY=1) message (" GC heap verification enabled") diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index 4c1fb064d..8ac519b77 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -91,8 +91,10 @@ endif () if (WAMR_BUILD_LIBC_UVWASI EQUAL 1) include (${IWASM_DIR}/libraries/libc-uvwasi/libc_uvwasi.cmake) + set (WAMR_BUILD_MODULE_INST_CONTEXT 1) elseif (WAMR_BUILD_LIBC_WASI EQUAL 1) include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake) + set (WAMR_BUILD_MODULE_INST_CONTEXT 1) endif () if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1) diff --git a/core/config.h b/core/config.h index 220f6751a..4bbb10234 100644 --- a/core/config.h +++ b/core/config.h @@ -480,4 +480,9 @@ #define WASM_MEM_DUAL_BUS_MIRROR 0 #endif +/* The max number of module instance contexts. */ +#ifndef WASM_MAX_INSTANCE_CONTEXTS +#define WASM_MAX_INSTANCE_CONTEXTS 8 +#endif + #endif /* end of _CONFIG_H_ */ diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 55c399a8b..55cf2d985 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1276,12 +1276,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) ->common.c_api_func_imports); if (!is_sub_inst) { -#if WASM_ENABLE_LIBC_WASI != 0 - wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst); -#endif #if WASM_ENABLE_WASI_NN != 0 wasi_nn_destroy(module_inst); #endif + wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst); } wasm_runtime_free(module_inst); diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index 1acaed6ee..0a5851349 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -6,6 +6,15 @@ #include "wasm_native.h" #include "wasm_runtime_common.h" #include "bh_log.h" +#if WASM_ENABLE_INTERP != 0 +#include "../interpreter/wasm_runtime.h" +#endif +#if WASM_ENABLE_AOT != 0 +#include "../aot/aot_runtime.h" +#endif +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif #if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \ && !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF) @@ -22,6 +31,10 @@ static NativeSymbolsList g_native_symbols_list = NULL; +#if WASM_ENABLE_LIBC_WASI != 0 +static void *g_wasi_context_key; +#endif /* WASM_ENABLE_LIBC_WASI */ + uint32 get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis); @@ -394,6 +407,155 @@ wasm_native_unregister_natives(const char *module_name, return false; } +#if WASM_ENABLE_MODULE_INST_CONTEXT != 0 +static uint32 +context_key_to_idx(void *key) +{ + bh_assert(key != NULL); + uint32 idx = (uint32)(uintptr_t)key; + bh_assert(idx > 0); + bh_assert(idx <= WASM_MAX_INSTANCE_CONTEXTS); + return idx - 1; +} + +static void * +context_idx_to_key(uint32 idx) +{ + bh_assert(idx < WASM_MAX_INSTANCE_CONTEXTS); + return (void *)(uintptr_t)(idx + 1); +} + +typedef void (*dtor_t)(WASMModuleInstanceCommon *, void *); +static dtor_t g_context_dtors[WASM_MAX_INSTANCE_CONTEXTS]; + +static void +dtor_noop(WASMModuleInstanceCommon *inst, void *ctx) +{} + +void * +wasm_native_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst, + void *ctx)) +{ + uint32 i; + for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) { + if (g_context_dtors[i] == NULL) { + if (dtor == NULL) { + dtor = dtor_noop; + } + g_context_dtors[i] = dtor; + return context_idx_to_key(i); + } + } + LOG_ERROR("failed to allocate instance context key"); + return NULL; +} + +void +wasm_native_destroy_context_key(void *key) +{ + uint32 idx = context_key_to_idx(key); + bh_assert(g_context_dtors[idx] != NULL); + g_context_dtors[idx] = NULL; +} + +static WASMModuleInstanceExtraCommon * +wasm_module_inst_extra_common(WASMModuleInstanceCommon *inst) +{ +#if WASM_ENABLE_INTERP != 0 + if (inst->module_type == Wasm_Module_Bytecode) { + return &((WASMModuleInstance *)inst)->e->common; + } +#endif +#if WASM_ENABLE_AOT != 0 + if (inst->module_type == Wasm_Module_AoT) { + return &((AOTModuleInstanceExtra *)((AOTModuleInstance *)inst)->e) + ->common; + } +#endif + bh_assert(false); + return NULL; +} + +void +wasm_native_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx) +{ + uint32 idx = context_key_to_idx(key); + WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst); + common->contexts[idx] = ctx; +} + +void +wasm_native_set_context_spread(WASMModuleInstanceCommon *inst, void *key, + void *ctx) +{ +#if WASM_ENABLE_THREAD_MGR != 0 + wasm_cluster_set_context(inst, key, ctx); +#else + wasm_native_set_context(inst, key, ctx); +#endif +} + +void * +wasm_native_get_context(WASMModuleInstanceCommon *inst, void *key) +{ + uint32 idx = context_key_to_idx(key); + WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst); + return common->contexts[idx]; +} + +void +wasm_native_call_context_dtors(WASMModuleInstanceCommon *inst) +{ + WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst); + uint32 i; + for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) { + dtor_t dtor = g_context_dtors[i]; + if (dtor != NULL) { + dtor(inst, common->contexts[i]); + } + } +} + +void +wasm_native_inherit_contexts(WASMModuleInstanceCommon *child, + WASMModuleInstanceCommon *parent) +{ + WASMModuleInstanceExtraCommon *parent_common = + wasm_module_inst_extra_common(parent); + WASMModuleInstanceExtraCommon *child_common = + wasm_module_inst_extra_common(child); + bh_memcpy_s(child_common->contexts, + sizeof(*child_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS, + parent_common->contexts, + sizeof(*parent_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS); +} +#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */ + +#if WASM_ENABLE_LIBC_WASI != 0 +WASIContext * +wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm) +{ + return wasm_native_get_context(module_inst_comm, g_wasi_context_key); +} + +void +wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm, + WASIContext *wasi_ctx) +{ + return wasm_native_set_context(module_inst_comm, g_wasi_context_key, + wasi_ctx); +} + +static void +wasi_context_dtor(WASMModuleInstanceCommon *inst, void *ctx) +{ + if (ctx == NULL) { + return; + } + wasm_runtime_destroy_wasi(inst); +} +#endif /* end of WASM_ENABLE_LIBC_WASI */ + bool wasm_native_init() { @@ -420,6 +582,10 @@ wasm_native_init() #endif /* WASM_ENABLE_SPEC_TEST */ #if WASM_ENABLE_LIBC_WASI != 0 + g_wasi_context_key = wasm_native_create_context_key(wasi_context_dtor); + if (g_wasi_context_key == NULL) { + goto fail; + } n_native_symbols = get_libc_wasi_export_apis(&native_symbols); if (!wasm_native_register_natives("wasi_unstable", native_symbols, n_native_symbols)) @@ -507,6 +673,12 @@ wasm_native_destroy() { NativeSymbolsNode *node, *node_next; +#if WASM_ENABLE_LIBC_WASI != 0 + if (g_wasi_context_key != NULL) { + wasm_native_destroy_context_key(g_wasi_context_key); + g_wasi_context_key = NULL; + } +#endif #if WASM_ENABLE_LIB_PTHREAD != 0 lib_pthread_destroy(); #endif diff --git a/core/iwasm/common/wasm_native.h b/core/iwasm/common/wasm_native.h index 4f6645d25..9ca5265c3 100644 --- a/core/iwasm/common/wasm_native.h +++ b/core/iwasm/common/wasm_native.h @@ -68,6 +68,36 @@ bool wasm_native_unregister_natives(const char *module_name, NativeSymbol *native_symbols); +#if WASM_ENABLE_MODULE_INST_CONTEXT != 0 +struct WASMModuleInstanceCommon; + +void * +wasm_native_create_context_key( + void (*dtor)(struct WASMModuleInstanceCommon *inst, void *ctx)); + +void +wasm_native_destroy_context_key(void *key); + +void +wasm_native_set_context(struct WASMModuleInstanceCommon *inst, void *key, + void *ctx); +void +wasm_native_set_context_spread(struct WASMModuleInstanceCommon *inst, void *key, + void *ctx); +void * +wasm_native_get_context(struct WASMModuleInstanceCommon *inst, void *key); + +void +wasm_native_call_context_dtors(struct WASMModuleInstanceCommon *inst); + +void +wasm_native_inherit_contexts(struct WASMModuleInstanceCommon *child, + struct WASMModuleInstanceCommon *parent); +#else /* WASM_ENABLE_MODULE_INST_CONTEXT */ +#define wasm_native_call_context_dtors(inst) (void)(inst) +#define wasm_native_inherit_contexts(child, parent) (void)(parent) +#endif /* WASM_ENABLE_MODULE_INST_CONTEXT */ + bool wasm_native_init(); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index ac85c61dc..cb7dbee9d 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3311,27 +3311,6 @@ wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst) #endif return wasi_ctx->exit_code; } - -WASIContext * -wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm) -{ - WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; - - bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode - || module_inst_comm->module_type == Wasm_Module_AoT); - return module_inst->wasi_ctx; -} - -void -wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm, - WASIContext *wasi_ctx) -{ - WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; - - bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode - || module_inst_comm->module_type == Wasm_Module_AoT); - module_inst->wasi_ctx = wasi_ctx; -} #endif /* end of WASM_ENABLE_LIBC_WASI */ WASMModuleCommon * @@ -5681,3 +5660,37 @@ wasm_runtime_is_import_global_linked(const char *module_name, return false; #endif } + +#if WASM_ENABLE_MODULE_INST_CONTEXT != 0 +void * +wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst, + void *ctx)) +{ + return wasm_native_create_context_key(dtor); +} + +void +wasm_runtime_destroy_context_key(void *key) +{ + wasm_native_destroy_context_key(key); +} + +void +wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx) +{ + wasm_native_set_context(inst, key, ctx); +} + +void +wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key, + void *ctx) +{ + wasm_native_set_context_spread(inst, key, ctx); +} + +void * +wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key) +{ + return wasm_native_get_context(inst, key); +} +#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */ diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index f631defb1..b9b0d0bf6 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -939,6 +939,26 @@ WASM_RUNTIME_API_EXTERN bool wasm_runtime_unregister_natives(const char *module_name, NativeSymbol *native_symbols); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void * +wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst, + void *ctx)); + +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_destroy_context_key(void *key); + +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key, + void *ctx); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void * +wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key); + bool wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, const WASMType *func_type, const char *signature, diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 79edc68ed..589d8af00 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1456,6 +1456,74 @@ WASM_RUNTIME_API_EXTERN void wasm_runtime_set_enlarge_mem_error_callback( const enlarge_memory_error_callback_t callback); +/* + * module instance context APIs + * wasm_runtime_create_context_key + * wasm_runtime_destroy_context_key + * wasm_runtime_set_context + * wasm_runtime_set_context_spread + * wasm_runtime_get_context + * + * This set of APIs is intended to be used by an embedder which provides + * extra sets of native functions, which need per module instance state + * and are maintained outside of the WAMR tree. + * + * It's modelled after the pthread specific API. + * + * wasm_runtime_set_context_spread is similar to + * wasm_runtime_set_context, except that + * wasm_runtime_set_context_spread applies the change + * to all threads in the cluster. + * It's an undefined behavior if multiple threads in a cluster call + * wasm_runtime_set_context_spread on the same key + * simultaneously. It's a caller's resposibility to perform necessary + * serialization if necessary. For example: + * + * if (wasm_runtime_get_context(inst, key) == NULL) { + * newctx = alloc_and_init(...); + * lock(some_lock); + * if (wasm_runtime_get_context(inst, key) == NULL) { + * // this thread won the race + * wasm_runtime_set_context_spread(inst, key, newctx); + * newctx = NULL; + * } + * unlock(some_lock); + * if (newctx != NULL) { + * // this thread lost the race, free it + * cleanup_and_free(newctx); + * } + * } + * + * Note: dynamic key create/destroy while instances are live is not + * implemented as of writing this. + * it's caller's resposibility to ensure destorying all module instances + * before calling wasm_runtime_create_context_key or + * wasm_runtime_destroy_context_key. + * otherwise, it's an undefined behavior. + * + * Note about threads: + * - When spawning a thread, the contexts (the pointers given to + * wasm_runtime_set_context) are copied from the parent + * instance. + * - The destructor is called only on the main instance. + */ + +WASM_RUNTIME_API_EXTERN void * +wasm_runtime_create_context_key( + void (*dtor)(wasm_module_inst_t inst, void *ctx)); + +WASM_RUNTIME_API_EXTERN void +wasm_runtime_destroy_context_key(void *key); + +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_context(wasm_module_inst_t inst, void *key, + void *ctx); +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key, + void *ctx); +WASM_RUNTIME_API_EXTERN void * +wasm_runtime_get_context(wasm_module_inst_t inst, void *key); + /* clang-format on */ #ifdef __cplusplus diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index f395b1eaa..301038a4d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2233,12 +2233,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) wasm_runtime_free(module_inst->e->common.c_api_func_imports); if (!is_sub_inst) { -#if WASM_ENABLE_LIBC_WASI != 0 - wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst); -#endif #if WASM_ENABLE_WASI_NN != 0 wasi_nn_destroy(module_inst); #endif + wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst); } wasm_runtime_free(module_inst); diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index aa33dc18c..605cefc6c 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -212,6 +212,7 @@ typedef struct CApiFuncImport { /* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */ typedef struct WASMModuleInstanceExtraCommon { + void *contexts[WASM_MAX_INSTANCE_CONTEXTS]; CApiFuncImport *c_api_func_imports; /* pointer to the exec env currently used */ WASMExecEnv *cur_exec_env; @@ -299,12 +300,8 @@ struct WASMModuleInstance { it denotes `AOTModule *` */ DefPointer(WASMModule *, module); -#if WASM_ENABLE_LIBC_WASI - /* WASI context */ - DefPointer(WASIContext *, wasi_ctx); -#else - DefPointer(void *, wasi_ctx); -#endif + DefPointer(void *, used_to_be_wasi_ctx); /* unused */ + DefPointer(WASMExecEnv *, exec_env_singleton); /* Array of function pointers to import functions, not available in AOTModuleInstance */ diff --git a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c index b8a641165..56deaff32 100644 --- a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c +++ b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c @@ -559,9 +559,6 @@ pthread_create_wrapper(wasm_exec_env_t exec_env, uint32 thread_handle; uint32 stack_size = 8192; int32 ret = -1; -#if WASM_ENABLE_LIBC_WASI != 0 - WASIContext *wasi_ctx; -#endif bh_assert(module); bh_assert(module_inst); @@ -588,11 +585,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env, wasm_runtime_set_custom_data_internal( new_module_inst, wasm_runtime_get_custom_data(module_inst)); -#if WASM_ENABLE_LIBC_WASI != 0 - wasi_ctx = get_wasi_ctx(module_inst); - if (wasi_ctx) - wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx); -#endif + wasm_native_inherit_contexts(new_module_inst, module_inst); if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) goto fail; diff --git a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c index a5f72986a..7e557be90 100644 --- a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c +++ b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c @@ -80,9 +80,6 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg) int32 thread_id; uint32 stack_size = 8192; int32 ret = -1; -#if WASM_ENABLE_LIBC_WASI != 0 - WASIContext *wasi_ctx; -#endif bh_assert(module); bh_assert(module_inst); @@ -99,11 +96,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg) if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) goto thread_preparation_fail; -#if WASM_ENABLE_LIBC_WASI != 0 - wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst); - if (wasi_ctx) - wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx); -#endif + wasm_native_inherit_contexts(new_module_inst, module_inst); start_func = wasm_runtime_lookup_function(new_module_inst, THREAD_START_FUNCTION, NULL); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 9a1e82d31..95f0d4267 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -480,9 +480,6 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env) wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_t module; wasm_module_inst_t new_module_inst; -#if WASM_ENABLE_LIBC_WASI != 0 - WASIContext *wasi_ctx; -#endif WASMExecEnv *new_exec_env; uint32 aux_stack_start, aux_stack_size; uint32 stack_size = 8192; @@ -520,10 +517,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env) wasm_runtime_set_custom_data_internal( new_module_inst, wasm_runtime_get_custom_data(module_inst)); -#if WASM_ENABLE_LIBC_WASI != 0 - wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst); - wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx); -#endif + wasm_native_inherit_contexts(new_module_inst, module_inst); new_exec_env = wasm_exec_env_create_internal(new_module_inst, exec_env->wasm_stack_size); @@ -1324,6 +1318,48 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst, } } +#if WASM_ENABLE_MODULE_INST_CONTEXT != 0 +struct inst_set_context_data { + void *key; + void *ctx; +}; + +static void +set_context_visitor(void *node, void *user_data) +{ + WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; + WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env); + const struct inst_set_context_data *data = user_data; + + wasm_runtime_set_context(module_inst, data->key, data->ctx); +} + +void +wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key, + void *ctx) +{ + WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst); + + if (exec_env == NULL) { + /* Maybe threads have not been started yet. */ + wasm_runtime_set_context(module_inst, key, ctx); + } + else { + WASMCluster *cluster; + struct inst_set_context_data data; + data.key = key; + data.ctx = ctx; + + cluster = wasm_exec_env_get_cluster(exec_env); + bh_assert(cluster); + + os_mutex_lock(&cluster->lock); + traverse_list(&cluster->exec_env_list, set_context_visitor, &data); + os_mutex_unlock(&cluster->lock); + } +} +#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */ + bool wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env) { diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index c6bc7a526..0280119fc 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -151,6 +151,10 @@ void wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst, void *custom_data); +void +wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key, + void *ctx); + bool wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env); diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index 2a0cec58c..e5af62cc8 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -253,10 +253,18 @@ CSRCS += posix.c CSRCS += random.c CSRCS += str.c VPATH += $(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/src +# todo: use Kconfig select instead +CONFIG_INTERPRETERS_WAMR_MODULE_INSTANCE_CONTEXT = y else CFLAGS += -DWASM_ENABLE_LIBC_WASI=0 endif +ifeq ($(CONFIG_INTERPRETERS_WAMR_MODULE_INSTANCE_CONTEXT),y) +CFLAGS += -DWASM_ENABLE_MODULE_INST_CONTEXT=1 +else +CFLAGS += -DWASM_ENABLE_MODULE_INST_CONTEXT=0 +endif + ifeq ($(CONFIG_INTERPRETERS_WAMR_MULTI_MODULE),y) CFLAGS += -DWASM_ENABLE_MULTI_MODULE=1 else diff --git a/samples/inst-context-threads/.gitignore b/samples/inst-context-threads/.gitignore new file mode 100644 index 000000000..0fa8a76bd --- /dev/null +++ b/samples/inst-context-threads/.gitignore @@ -0,0 +1 @@ +/out/ \ No newline at end of file diff --git a/samples/inst-context-threads/CMakeLists.txt b/samples/inst-context-threads/CMakeLists.txt new file mode 100644 index 000000000..7326a5436 --- /dev/null +++ b/samples/inst-context-threads/CMakeLists.txt @@ -0,0 +1,92 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 3.14) + +include(CheckPIESupported) + +if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows") + project (inst-context) +else() + project (inst-context C ASM) + enable_language (ASM_MASM) +endif() + +################ runtime settings ################ +string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) +if (APPLE) + add_definitions(-DBH_PLATFORM_DARWIN) +endif () + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# WAMR features switch + +# Set WAMR_BUILD_TARGET, currently values supported: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Debug) +endif () + +set (WAMR_BUILD_INTERP 1) +set (WAMR_BUILD_AOT 1) +set (WAMR_BUILD_JIT 0) +set (WAMR_BUILD_LIBC_BUILTIN 0) +set (WAMR_BUILD_LIB_WASI_THREADS 1) + +if (NOT MSVC) + set (WAMR_BUILD_LIBC_WASI 1) +endif () + +if (NOT MSVC) + # linker flags + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") + endif () + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") + if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") + endif () + endif () +endif () + +# build out vmlib +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) + +add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) + +################ application related ################ +include_directories(${CMAKE_CURRENT_LIST_DIR}/src) +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +add_executable (inst-context src/main.c src/native_impl.c ${UNCOMMON_SHARED_SOURCE}) + +check_pie_supported() +set_target_properties (inst-context PROPERTIES POSITION_INDEPENDENT_CODE ON) + +if (APPLE) + target_link_libraries (inst-context vmlib -lm -ldl -lpthread) +else () + target_link_libraries (inst-context vmlib -lm -ldl -lpthread -lrt) +endif () diff --git a/samples/inst-context-threads/README.md b/samples/inst-context-threads/README.md new file mode 100644 index 000000000..43b13c66b --- /dev/null +++ b/samples/inst-context-threads/README.md @@ -0,0 +1,4 @@ +The "inst-context" sample project +================================= + +This sample demonstrates module instance context API. diff --git a/samples/inst-context-threads/build.sh b/samples/inst-context-threads/build.sh new file mode 100755 index 000000000..35f76eccf --- /dev/null +++ b/samples/inst-context-threads/build.sh @@ -0,0 +1,61 @@ +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +#!/bin/bash + +CURR_DIR=$PWD +WAMR_DIR=${PWD}/../.. +OUT_DIR=${PWD}/out + +WASM_APPS=${PWD}/wasm-apps + + +rm -rf ${OUT_DIR} +mkdir ${OUT_DIR} +mkdir ${OUT_DIR}/wasm-apps + + +echo "#####################build inst-context project" +cd ${CURR_DIR} +mkdir -p cmake_build +cd cmake_build +cmake .. +make -j ${nproc} +if [ $? != 0 ];then + echo "BUILD_FAIL inst-context exit as $?\n" + exit 2 +fi + +cp -a inst-context ${OUT_DIR} + +echo -e "\n" + +echo "#####################build wasm apps" + +cd ${WASM_APPS} + +for i in `ls *.c` +do +APP_SRC="$i" +OUT_FILE=${i%.*}.wasm + +# use WAMR SDK to build out the .wasm binary +# require wasi-sdk with wasi-threads support. (wasi-sdk-20.0 or later) +/opt/wasi-sdk/bin/clang \ + --target=wasm32-wasi-threads \ + -pthread \ + -Wl,--import-memory \ + -Wl,--export-memory \ + -Wl,--max-memory=655360 \ + -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} + + +if [ -f ${OUT_DIR}/wasm-apps/${OUT_FILE} ]; then + echo "build ${OUT_FILE} success" +else + echo "build ${OUT_FILE} fail" +fi +done +echo "####################build wasm apps done" diff --git a/samples/inst-context-threads/run.sh b/samples/inst-context-threads/run.sh new file mode 100755 index 000000000..919ed0166 --- /dev/null +++ b/samples/inst-context-threads/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +out/inst-context -f out/wasm-apps/testapp.wasm diff --git a/samples/inst-context-threads/src/main.c b/samples/inst-context-threads/src/main.c new file mode 100644 index 000000000..2a20363c5 --- /dev/null +++ b/samples/inst-context-threads/src/main.c @@ -0,0 +1,151 @@ + +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_export.h" +#include "bh_read_file.h" +#include "bh_getopt.h" +#include "my_context.h" + +void +set_context(wasm_exec_env_t exec_env, int32_t n); +int32_t +get_context(wasm_exec_env_t exec_env); + +void *my_context_key; +struct my_context my_context; +int my_dtor_called; + +wasm_module_inst_t module_inst = NULL; + +void +print_usage(void) +{ + fprintf(stdout, "Options:\r\n"); + fprintf(stdout, " -f [path of wasm file] \n"); +} + +void +my_context_dtor(wasm_module_inst_t inst, void *ctx) +{ + printf("%s called\n", __func__); + my_dtor_called++; + bh_assert(ctx == &my_context); + bh_assert(inst == module_inst); +} + +int +main(int argc, char *argv_main[]) +{ + static char global_heap_buf[512 * 1024]; + char *buffer; + char error_buf[128]; + int opt; + char *wasm_path = NULL; + int exit_code = 1; + + wasm_module_t module = NULL; + uint32 buf_size, stack_size = 8092, heap_size = 8092; + + RuntimeInitArgs init_args; + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + while ((opt = getopt(argc, argv_main, "hf:")) != -1) { + switch (opt) { + case 'f': + wasm_path = optarg; + break; + case 'h': + print_usage(); + return 0; + case '?': + print_usage(); + return 0; + } + } + if (optind == 1) { + print_usage(); + return 0; + } + + // Define an array of NativeSymbol for the APIs to be exported. + // Note: the array must be static defined since runtime + // will keep it after registration + // For the function signature specifications, goto the link: + // https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md + + static NativeSymbol native_symbols[] = { + { "set_context", set_context, "(i)", NULL }, + { "get_context", get_context, "()i", NULL }, + }; + + init_args.mem_alloc_type = Alloc_With_Pool; + init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; + init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); + + // Native symbols need below registration phase + init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol); + init_args.native_module_name = "env"; + init_args.native_symbols = native_symbols; + + if (!wasm_runtime_full_init(&init_args)) { + printf("Init runtime environment failed.\n"); + return -1; + } + + my_context_key = wasm_runtime_create_context_key(my_context_dtor); + if (!my_context_key) { + printf("wasm_runtime_create_context_key failed.\n"); + return -1; + } + + buffer = bh_read_file_to_buffer(wasm_path, &buf_size); + + if (!buffer) { + printf("Open wasm app file [%s] failed.\n", wasm_path); + goto fail; + } + + module = wasm_runtime_load((uint8 *)buffer, buf_size, error_buf, + sizeof(error_buf)); + if (!module) { + printf("Load wasm module failed. error: %s\n", error_buf); + goto fail; + } + + module_inst = wasm_runtime_instantiate(module, stack_size, heap_size, + error_buf, sizeof(error_buf)); + + if (!module_inst) { + printf("Instantiate wasm module failed. error: %s\n", error_buf); + goto fail; + } + + char *args[] = { + "testapp", + }; + wasm_application_execute_main(module_inst, 1, args); + const char *exc = wasm_runtime_get_exception(module_inst); + if (exc != NULL) { + printf("call wasm function calculate failed. error: %s\n", exc); + goto fail; + } + + exit_code = 0; +fail: + if (module_inst) { + bh_assert(my_dtor_called == 0); + wasm_runtime_deinstantiate(module_inst); + bh_assert(my_dtor_called == 1); + } + if (module) + wasm_runtime_unload(module); + if (buffer) + BH_FREE(buffer); + if (my_context_key) + wasm_runtime_destroy_context_key(my_context_key); + wasm_runtime_destroy(); + return exit_code; +} diff --git a/samples/inst-context-threads/src/my_context.h b/samples/inst-context-threads/src/my_context.h new file mode 100644 index 000000000..008be71ff --- /dev/null +++ b/samples/inst-context-threads/src/my_context.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +struct my_context { + int x; +}; + +extern void *my_context_key; +extern struct my_context my_context; diff --git a/samples/inst-context-threads/src/native_impl.c b/samples/inst-context-threads/src/native_impl.c new file mode 100644 index 000000000..0733e1976 --- /dev/null +++ b/samples/inst-context-threads/src/native_impl.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include + +#include "wasm_export.h" +#include "my_context.h" + +void +set_context(wasm_exec_env_t exec_env, int32_t n) +{ + wasm_module_inst_t inst = wasm_runtime_get_module_inst(exec_env); + printf("%s called on module inst %p\n", __func__, inst); + struct my_context *ctx = &my_context; + ctx->x = n; + wasm_runtime_set_context_spread(inst, my_context_key, ctx); +} + +int32_t +get_context(wasm_exec_env_t exec_env) +{ + wasm_module_inst_t inst = wasm_runtime_get_module_inst(exec_env); + printf("%s called on module inst %p\n", __func__, inst); + struct my_context *ctx = wasm_runtime_get_context(inst, my_context_key); + if (ctx == NULL) { + return -1; + } + return ctx->x; +} diff --git a/samples/inst-context-threads/wasm-apps/testapp.c b/samples/inst-context-threads/wasm-apps/testapp.c new file mode 100644 index 000000000..429b0875f --- /dev/null +++ b/samples/inst-context-threads/wasm-apps/testapp.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include +#include +#include + +void +set_context(int32_t n) __attribute__((import_module("env"))) +__attribute__((import_name("set_context"))); + +int32_t +get_context() __attribute__((import_module("env"))) +__attribute__((import_name("get_context"))); + +void * +start(void *vp) +{ + int32_t v; + + printf("thread started\n"); + + printf("confirming the initial state on thread\n"); + v = get_context(); + assert(v == -1); + + printf("setting the context on thread\n"); + set_context(1234); + + printf("confirming the context on thread\n"); + v = get_context(); + assert(v == 1234); + return NULL; +} + +int +main() +{ + pthread_t t1; + int32_t v; + int ret; + + printf("confirming the initial state on main\n"); + v = get_context(); + assert(v == -1); + + printf("creating a thread\n"); + ret = pthread_create(&t1, NULL, start, NULL); + assert(ret == 0); + void *val; + ret = pthread_join(t1, &val); + assert(ret == 0); + printf("joined the thread\n"); + + printf("confirming the context propagated from the thread on main\n"); + v = get_context(); + assert(v == 1234); + + printf("success\n"); + return 0; +} diff --git a/samples/inst-context/.gitignore b/samples/inst-context/.gitignore new file mode 100644 index 000000000..0fa8a76bd --- /dev/null +++ b/samples/inst-context/.gitignore @@ -0,0 +1 @@ +/out/ \ No newline at end of file diff --git a/samples/inst-context/CMakeLists.txt b/samples/inst-context/CMakeLists.txt new file mode 100644 index 000000000..b1167d277 --- /dev/null +++ b/samples/inst-context/CMakeLists.txt @@ -0,0 +1,91 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 3.14) + +include(CheckPIESupported) + +if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows") + project (inst-context) +else() + project (inst-context C ASM) + enable_language (ASM_MASM) +endif() + +################ runtime settings ################ +string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) +if (APPLE) + add_definitions(-DBH_PLATFORM_DARWIN) +endif () + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# WAMR features switch + +# Set WAMR_BUILD_TARGET, currently values supported: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Debug) +endif () + +set (WAMR_BUILD_INTERP 1) +set (WAMR_BUILD_AOT 1) +set (WAMR_BUILD_JIT 0) +set (WAMR_BUILD_LIBC_BUILTIN 1) + +if (NOT MSVC) + set (WAMR_BUILD_LIBC_WASI 1) +endif () + +if (NOT MSVC) + # linker flags + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") + endif () + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") + if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") + endif () + endif () +endif () + +# build out vmlib +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) + +add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) + +################ application related ################ +include_directories(${CMAKE_CURRENT_LIST_DIR}/src) +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +add_executable (inst-context src/main.c src/native_impl.c ${UNCOMMON_SHARED_SOURCE}) + +check_pie_supported() +set_target_properties (inst-context PROPERTIES POSITION_INDEPENDENT_CODE ON) + +if (APPLE) + target_link_libraries (inst-context vmlib -lm -ldl -lpthread) +else () + target_link_libraries (inst-context vmlib -lm -ldl -lpthread -lrt) +endif () diff --git a/samples/inst-context/README.md b/samples/inst-context/README.md new file mode 100644 index 000000000..43b13c66b --- /dev/null +++ b/samples/inst-context/README.md @@ -0,0 +1,4 @@ +The "inst-context" sample project +================================= + +This sample demonstrates module instance context API. diff --git a/samples/inst-context/build.sh b/samples/inst-context/build.sh new file mode 100755 index 000000000..816e1cc08 --- /dev/null +++ b/samples/inst-context/build.sh @@ -0,0 +1,63 @@ +# +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# + +#!/bin/bash + +CURR_DIR=$PWD +WAMR_DIR=${PWD}/../.. +OUT_DIR=${PWD}/out + +WASM_APPS=${PWD}/wasm-apps + + +rm -rf ${OUT_DIR} +mkdir ${OUT_DIR} +mkdir ${OUT_DIR}/wasm-apps + + +echo "#####################build inst-context project" +cd ${CURR_DIR} +mkdir -p cmake_build +cd cmake_build +cmake .. +make -j ${nproc} +if [ $? != 0 ];then + echo "BUILD_FAIL inst-context exit as $?\n" + exit 2 +fi + +cp -a inst-context ${OUT_DIR} + +echo -e "\n" + +echo "#####################build wasm apps" + +cd ${WASM_APPS} + +for i in `ls *.c` +do +APP_SRC="$i" +OUT_FILE=${i%.*}.wasm + +# use WAMR SDK to build out the .wasm binary +/opt/wasi-sdk/bin/clang \ + --target=wasm32 -O0 -z stack-size=4096 -Wl,--initial-memory=65536 \ + --sysroot=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot \ + -Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt \ + -Wl,--strip-all,--no-entry -nostdlib \ + -Wl,--export=generate_float \ + -Wl,--export=float_to_string \ + -Wl,--export=calculate\ + -Wl,--allow-undefined \ + -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} + + +if [ -f ${OUT_DIR}/wasm-apps/${OUT_FILE} ]; then + echo "build ${OUT_FILE} success" +else + echo "build ${OUT_FILE} fail" +fi +done +echo "####################build wasm apps done" diff --git a/samples/inst-context/run.sh b/samples/inst-context/run.sh new file mode 100755 index 000000000..919ed0166 --- /dev/null +++ b/samples/inst-context/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +out/inst-context -f out/wasm-apps/testapp.wasm diff --git a/samples/inst-context/src/main.c b/samples/inst-context/src/main.c new file mode 100644 index 000000000..0d774735e --- /dev/null +++ b/samples/inst-context/src/main.c @@ -0,0 +1,166 @@ + +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_export.h" +#include "bh_read_file.h" +#include "bh_getopt.h" +#include "my_context.h" + +int32_t +add_native(int32_t n); +void *my_context_key; +struct my_context my_context; +int my_dtor_called; + +wasm_module_inst_t module_inst = NULL; + +void +print_usage(void) +{ + fprintf(stdout, "Options:\r\n"); + fprintf(stdout, " -f [path of wasm file] \n"); +} + +void +my_context_dtor(wasm_module_inst_t inst, void *ctx) +{ + printf("%s called\n", __func__); + my_dtor_called++; + bh_assert(ctx == &my_context); + bh_assert(inst == module_inst); +} + +int +main(int argc, char *argv_main[]) +{ + static char global_heap_buf[512 * 1024]; + char *buffer; + char error_buf[128]; + int opt; + char *wasm_path = NULL; + + wasm_module_t module = NULL; + wasm_exec_env_t exec_env = NULL; + uint32 buf_size, stack_size = 8092, heap_size = 8092; + + RuntimeInitArgs init_args; + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + while ((opt = getopt(argc, argv_main, "hf:")) != -1) { + switch (opt) { + case 'f': + wasm_path = optarg; + break; + case 'h': + print_usage(); + return 0; + case '?': + print_usage(); + return 0; + } + } + if (optind == 1) { + print_usage(); + return 0; + } + + // Define an array of NativeSymbol for the APIs to be exported. + // Note: the array must be static defined since runtime + // will keep it after registration + // For the function signature specifications, goto the link: + // https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md + + static NativeSymbol native_symbols[] = { { "add_native", add_native, "(i)i", + NULL } }; + + init_args.mem_alloc_type = Alloc_With_Pool; + init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; + init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); + + // Native symbols need below registration phase + init_args.n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol); + init_args.native_module_name = "env"; + init_args.native_symbols = native_symbols; + + if (!wasm_runtime_full_init(&init_args)) { + printf("Init runtime environment failed.\n"); + return -1; + } + + my_context_key = wasm_runtime_create_context_key(my_context_dtor); + if (!my_context_key) { + printf("wasm_runtime_create_context_key failed.\n"); + return -1; + } + + buffer = bh_read_file_to_buffer(wasm_path, &buf_size); + + if (!buffer) { + printf("Open wasm app file [%s] failed.\n", wasm_path); + goto fail; + } + + module = wasm_runtime_load((uint8 *)buffer, buf_size, error_buf, + sizeof(error_buf)); + if (!module) { + printf("Load wasm module failed. error: %s\n", error_buf); + goto fail; + } + + module_inst = wasm_runtime_instantiate(module, stack_size, heap_size, + error_buf, sizeof(error_buf)); + + if (!module_inst) { + printf("Instantiate wasm module failed. error: %s\n", error_buf); + goto fail; + } + + my_context.x = 100; + wasm_runtime_set_context(module_inst, my_context_key, &my_context); + + exec_env = wasm_runtime_create_exec_env(module_inst, stack_size); + if (!exec_env) { + printf("Create wasm execution environment failed.\n"); + goto fail; + } + + wasm_function_inst_t func3 = + wasm_runtime_lookup_function(module_inst, "calculate", NULL); + if (!func3) { + printf("The wasm function calculate is not found.\n"); + goto fail; + } + + uint32_t argv3[1] = { 3 }; + if (wasm_runtime_call_wasm(exec_env, func3, 1, argv3)) { + uint32_t result = *(uint32_t *)argv3; + printf("Native finished calling wasm function: calculate, return: %d\n", + result); + bh_assert(result == 103); /* argv3[0] + my_context.x */ + } + else { + printf("call wasm function calculate failed. error: %s\n", + wasm_runtime_get_exception(module_inst)); + goto fail; + } + +fail: + if (exec_env) + wasm_runtime_destroy_exec_env(exec_env); + if (module_inst) { + bh_assert(my_dtor_called == 0); + wasm_runtime_deinstantiate(module_inst); + bh_assert(my_dtor_called == 1); + } + if (module) + wasm_runtime_unload(module); + if (buffer) + BH_FREE(buffer); + if (my_context_key) + wasm_runtime_destroy_context_key(my_context_key); + wasm_runtime_destroy(); + return 0; +} diff --git a/samples/inst-context/src/my_context.h b/samples/inst-context/src/my_context.h new file mode 100644 index 000000000..db49c1e3b --- /dev/null +++ b/samples/inst-context/src/my_context.h @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +struct my_context { + int x; +}; + +extern void *my_context_key; diff --git a/samples/inst-context/src/native_impl.c b/samples/inst-context/src/native_impl.c new file mode 100644 index 000000000..1254b4a22 --- /dev/null +++ b/samples/inst-context/src/native_impl.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_export.h" +#include "my_context.h" + +int32_t +add_native(wasm_exec_env_t exec_env, int32_t n) +{ + wasm_module_inst_t inst = wasm_runtime_get_module_inst(exec_env); + struct my_context *ctx = wasm_runtime_get_context(inst, my_context_key); + return n + ctx->x; +} diff --git a/samples/inst-context/wasm-apps/testapp.c b/samples/inst-context/wasm-apps/testapp.c new file mode 100644 index 000000000..1774dcd07 --- /dev/null +++ b/samples/inst-context/wasm-apps/testapp.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include +#include + +int32_t +add_native(int32_t n); + +int32_t +calculate(int32_t n) +{ + printf("calling into WASM function: %s\n", __FUNCTION__); + return add_native(n); +} diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 08f935bb6..ba0902cdf 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -45,6 +45,7 @@ add_definitions(-DWASM_ENABLE_DUMP_CALL_STACK=1) add_definitions(-DWASM_ENABLE_PERF_PROFILING=1) add_definitions(-DWASM_ENABLE_LOAD_CUSTOM_SECTION=1) add_definitions(-DWASM_ENABLE_LIB_WASI_THREADS=1) +add_definitions(-DWASM_ENABLE_MODULE_INST_CONTEXT=1) if (WAMR_BUILD_LLVM_LEGACY_PM EQUAL 1) add_definitions(-DWASM_ENABLE_LLVM_LEGACY_PM=1) From 534a8cf9f4b812950155abf17d98430e1d5599e9 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 8 Sep 2023 12:49:04 +0900 Subject: [PATCH 15/58] Handle a return from wasi _start function correctly (#2529) This fixes a few test cases in wasi-threads testsuite like wasi_threads_return_main_block. And also move the special handling for "wasi proc exit" to a more appropriate place. --- core/iwasm/common/wasm_application.c | 29 ++++++++++++++++- core/iwasm/common/wasm_runtime_common.c | 42 ++----------------------- 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 2ed217e7a..795d65c8c 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -107,7 +107,34 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) the actual main function. Directly calling main function may cause exception thrown. */ if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) { - return wasm_runtime_call_wasm(exec_env, func, 0, NULL); + const char *wasi_proc_exit_exception = "wasi proc exit"; + + ret = wasm_runtime_call_wasm(exec_env, func, 0, NULL); +#if WASM_ENABLE_THREAD_MGR != 0 + if (ret) { + /* On a successful return from the `_start` function, + we terminate other threads by mimicing wasi:proc_exit(0). + + Note: + - A return from the `main` function is an equivalent of + exit(). (C standard) + - When exit code is 0, wasi-libc's `_start` function just + returns w/o calling `proc_exit`. + - A process termination should terminate threads in + the process. */ + + wasm_runtime_set_exception(module_inst, wasi_proc_exit_exception); + /* exit_code is zero-initialized */ + ret = false; + } +#endif + /* report wasm proc exit as a success */ + WASMModuleInstance *inst = (WASMModuleInstance *)module_inst; + if (!ret && strstr(inst->cur_exception, wasi_proc_exit_exception)) { + inst->cur_exception[0] = 0; + ret = true; + } + return ret; } #endif /* end of WASM_ENABLE_LIBC_WASI */ diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index cb7dbee9d..7cac9e643 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1938,33 +1938,6 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env, } #endif -static bool -clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm) -{ -#if WASM_ENABLE_LIBC_WASI != 0 - bool has_exception; - char exception[EXCEPTION_BUF_LEN]; - WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; - - bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode - || module_inst_comm->module_type == Wasm_Module_AoT); - - has_exception = wasm_copy_exception(module_inst, exception); - if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) { - /* The "wasi proc exit" exception is thrown by native lib to - let wasm app exit, which is a normal behavior, we clear - the exception here. And just clear the exception of current - thread, don't call `wasm_set_exception(module_inst, NULL)` - which will clear the exception of all threads. */ - module_inst->cur_exception[0] = '\0'; - return true; - } - return false; -#else - return false; -#endif -} - bool wasm_runtime_call_wasm(WASMExecEnv *exec_env, WASMFunctionInstanceCommon *function, uint32 argc, @@ -2005,15 +1978,10 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env, param_argc, new_argv); #endif if (!ret) { - if (clear_wasi_proc_exit_exception(exec_env->module_inst)) { - ret = true; - } - else { - if (new_argv != argv) { - wasm_runtime_free(new_argv); - } - return false; + if (new_argv != argv) { + wasm_runtime_free(new_argv); } + return false; } #if WASM_ENABLE_REF_TYPES != 0 @@ -4573,10 +4541,6 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index, ret = aot_call_indirect(exec_env, 0, element_index, argc, argv); #endif - if (!ret && clear_wasi_proc_exit_exception(exec_env->module_inst)) { - ret = true; - } - return ret; } From f128150d436ca112f695e3eda418c248b1f650c5 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 8 Sep 2023 13:26:32 +0900 Subject: [PATCH 16/58] fd_object_release: Preserve errno (#2535) Preserve errno because this function is often used like the following. The caller wants to report the error from the main operation (`lseek` in this example), not from fd_object_release. ``` off_t ret = lseek(fd_number(fo), offset, nwhence); fd_object_release(fo); if (ret < 0) return convert_errno(errno); ``` --- .../libraries/libc-wasi/sandboxed-system-primitives/src/posix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 2af2f2d02..a9831d770 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -642,6 +642,7 @@ static void fd_object_release(struct fd_object *fo) UNLOCKS(fo->refcount) { if (refcount_release(&fo->refcount)) { + int saved_errno = errno; switch (fo->type) { case __WASI_FILETYPE_DIRECTORY: // For directories we may keep track of a DIR object. Calling @@ -659,6 +660,7 @@ fd_object_release(struct fd_object *fo) UNLOCKS(fo->refcount) break; } wasm_runtime_free(fo); + errno = saved_errno; } } From a6fda9b7ab145222b6dab9929e71147bc061da97 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 13 Sep 2023 18:09:31 +0900 Subject: [PATCH 17/58] Add an API to terminate instance (#2538) Add API wasm_runtime_terminate to terminate a module instance by setting "terminated by user" exception to the module instance. And update the product-mini of posix platforms. Note: this doesn't work for some situations like blocking system calls. --- core/iwasm/common/wasm_runtime_common.c | 27 ++++++- core/iwasm/common/wasm_runtime_common.h | 4 ++ core/iwasm/include/wasm_export.h | 21 ++++++ .../libraries/thread-mgr/thread_manager.c | 16 ++++- .../libraries/thread-mgr/thread_manager.h | 2 +- product-mini/platforms/posix/main.c | 72 +++++++++++++++++++ 6 files changed, 136 insertions(+), 6 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 7cac9e643..3a2f44c5f 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2342,8 +2342,8 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm) return module_inst->exec_env_singleton; } -void -wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) +static void +wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception) { exception_lock(module_inst); if (exception) { @@ -2354,13 +2354,22 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) module_inst->cur_exception[0] = '\0'; } exception_unlock(module_inst); +} +void +wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) +{ #if WASM_ENABLE_THREAD_MGR != 0 WASMExecEnv *exec_env = wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); if (exec_env) { - wasm_cluster_spread_exception(exec_env, exception); + wasm_cluster_set_exception(exec_env, exception); } + else { + wasm_set_exception_local(module_inst, exception); + } +#else + wasm_set_exception_local(module_inst, exception); #endif } @@ -2468,6 +2477,18 @@ wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm) wasm_runtime_set_exception(module_inst_comm, NULL); } +#if WASM_ENABLE_THREAD_MGR != 0 +void +wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm) +{ + WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; + + bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode + || module_inst_comm->module_type == Wasm_Module_AoT); + wasm_set_exception(module_inst, "terminated by user"); +} +#endif + void wasm_runtime_set_custom_data_internal( WASMModuleInstanceCommon *module_inst_comm, void *custom_data) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index b9b0d0bf6..4e3bc80af 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -675,6 +675,10 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module); WASM_RUNTIME_API_EXTERN void wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_terminate(WASMModuleInstanceCommon *module); + /* Internal API */ void wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst, diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 589d8af00..559f3d22e 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -894,6 +894,27 @@ wasm_runtime_set_exception(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_clear_exception(wasm_module_inst_t module_inst); +/** + * Terminate the WASM module instance. + * + * This function causes the module instance fail as if it raised a trap. + * + * This is intended to be used in situations like: + * + * - A thread is executing the WASM module instance + * (eg. it's in the middle of `wasm_application_execute_main`) + * + * - Another thread has a copy of `wasm_module_inst_t` of + * the module instance and wants to terminate it asynchronously. + * + * This function is provided only when WAMR is built with threading enabled. + * (`WASM_ENABLE_THREAD_MGR=1`) + * + * @param module_inst the WASM module instance + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_terminate(wasm_module_inst_t module_inst); + /** * Set custom data to WASM module instance. * Note: diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 95f0d4267..06be3bc89 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -1061,6 +1061,15 @@ set_thread_cancel_flags(WASMExecEnv *exec_env) os_mutex_unlock(&exec_env->wait_lock); } +static void +clear_thread_cancel_flags(WASMExecEnv *exec_env) +{ + os_mutex_lock(&exec_env->wait_lock); + WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags, + ~WASM_SUSPEND_FLAG_TERMINATE); + os_mutex_unlock(&exec_env->wait_lock); +} + int32 wasm_cluster_cancel_thread(WASMExecEnv *exec_env) { @@ -1266,18 +1275,21 @@ set_exception_visitor(void *node, void *user_data) if (data->exception != NULL) { set_thread_cancel_flags(exec_env); } + else { + clear_thread_cancel_flags(exec_env); + } } } void -wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception) +wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception) { const bool has_exception = exception != NULL; WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env); bh_assert(cluster); struct spread_exception_data data; - data.skip = exec_env; + data.skip = NULL; data.exception = exception; os_mutex_lock(&cluster->lock); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 0280119fc..19186f597 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -139,7 +139,7 @@ WASMExecEnv * wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst); void -wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception); +wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception); WASMExecEnv * wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env); diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 6d4ada662..d61557022 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -97,6 +97,11 @@ print_help() #if WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0 printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n"); #endif +#if WASM_ENABLE_THREAD_MGR != 0 + printf(" --timeout=ms Set the maximum execution time in ms.\n"); + printf(" If it expires, the runtime aborts the execution\n"); + printf(" with a trap.\n"); +#endif #if WASM_ENABLE_DEBUG_INTERP != 0 printf(" -g=ip:port Set the debug sever address, default is debug disabled\n"); printf(" if port is 0, then a random port will be used\n"); @@ -488,6 +493,37 @@ dump_pgo_prof_data(wasm_module_inst_t module_inst, const char *path) } #endif +#if WASM_ENABLE_THREAD_MGR != 0 +struct timeout_arg { + uint32 timeout_ms; + wasm_module_inst_t inst; + _Atomic bool cancel; +}; + +void * +timeout_thread(void *vp) +{ + const struct timeout_arg *arg = vp; + uint32 left = arg->timeout_ms; + while (!arg->cancel) { + uint32 ms; + if (left >= 100) { + ms = 100; + } + else { + ms = left; + } + os_usleep((uint64)ms * 1000); + left -= ms; + if (left == 0) { + wasm_runtime_terminate(arg->inst); + break; + } + } + return NULL; +} +#endif + int main(int argc, char *argv[]) { @@ -546,6 +582,9 @@ main(int argc, char *argv[]) #if WASM_ENABLE_STATIC_PGO != 0 const char *gen_prof_file = NULL; #endif +#if WASM_ENABLE_THREAD_MGR != 0 + int timeout_ms = -1; +#endif /* Process options. */ for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { @@ -742,6 +781,13 @@ main(int argc, char *argv[]) wasm_runtime_set_max_thread_num(atoi(argv[0] + 14)); } #endif +#if WASM_ENABLE_THREAD_MGR != 0 + else if (!strncmp(argv[0], "--timeout=", 10)) { + if (argv[0][10] == '\0') + return print_help(); + timeout_ms = atoi(argv[0] + 10); + } +#endif #if WASM_ENABLE_DEBUG_INTERP != 0 else if (!strncmp(argv[0], "-g=", 3)) { char *port_str = strchr(argv[0] + 3, ':'); @@ -902,6 +948,22 @@ main(int argc, char *argv[]) } #endif +#if WASM_ENABLE_THREAD_MGR != 0 + struct timeout_arg timeout_arg; + korp_tid timeout_tid; + if (timeout_ms >= 0) { + timeout_arg.timeout_ms = timeout_ms; + timeout_arg.inst = wasm_module_inst; + timeout_arg.cancel = false; + ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg, + APP_THREAD_STACK_SIZE_DEFAULT); + if (ret != 0) { + printf("Failed to start timeout\n"); + goto fail5; + } + } +#endif + ret = 0; if (is_repl_mode) { app_instance_repl(wasm_module_inst); @@ -932,6 +994,16 @@ main(int argc, char *argv[]) dump_pgo_prof_data(wasm_module_inst, gen_prof_file); #endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (timeout_ms >= 0) { + timeout_arg.cancel = true; + os_thread_join(timeout_tid, NULL); + } +#endif + +#if WASM_ENABLE_THREAD_MGR != 0 +fail5: +#endif #if WASM_ENABLE_DEBUG_INTERP != 0 fail4: #endif From 83db970953c460738701f0edbf7eb10666e59452 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Wed, 13 Sep 2023 12:03:49 +0200 Subject: [PATCH 18/58] Add user to enlarge memory error callback (#2546) --- core/iwasm/common/wasm_memory.c | 10 +++++++--- core/iwasm/common/wasm_memory.h | 2 +- core/iwasm/include/wasm_export.h | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index a083a214e..05635ef51 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -26,6 +26,7 @@ static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN; static mem_allocator_t pool_allocator = NULL; static enlarge_memory_error_callback_t enlarge_memory_error_cb; +static void *enlarge_memory_error_user_data; #if WASM_MEM_ALLOC_WITH_USER_DATA != 0 static void *allocator_user_data = NULL; @@ -716,7 +717,8 @@ return_func: enlarge_memory_error_cb(inc_page_count, total_size_old, 0, failure_reason, - (WASMModuleInstanceCommon *)module, exec_env); + (WASMModuleInstanceCommon *)module, exec_env, + enlarge_memory_error_user_data); } return ret; @@ -822,7 +824,8 @@ return_func: enlarge_memory_error_cb(inc_page_count, total_size_old, 0, failure_reason, - (WASMModuleInstanceCommon *)module, exec_env); + (WASMModuleInstanceCommon *)module, exec_env, + enlarge_memory_error_user_data); } return ret; @@ -831,9 +834,10 @@ return_func: void wasm_runtime_set_enlarge_mem_error_callback( - const enlarge_memory_error_callback_t callback) + const enlarge_memory_error_callback_t callback, void *user_data) { enlarge_memory_error_cb = callback; + enlarge_memory_error_user_data = user_data; } bool diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index cf7d7ffcd..daca2b71e 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -26,7 +26,7 @@ wasm_runtime_memory_pool_size(); void wasm_runtime_set_enlarge_mem_error_callback( - const enlarge_memory_error_callback_t callback); + const enlarge_memory_error_callback_t callback, void *user_data); #ifdef __cplusplus } diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 559f3d22e..34206db29 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1468,14 +1468,15 @@ typedef enum { typedef void (*enlarge_memory_error_callback_t)( uint32_t inc_page_count, uint64_t current_memory_size, uint32_t memory_index, enlarge_memory_error_reason_t failure_reason, - wasm_module_inst_t instance, wasm_exec_env_t exec_env); + wasm_module_inst_t instance, wasm_exec_env_t exec_env, + void* user_data); /** * Setup callback invoked when memory.grow fails */ WASM_RUNTIME_API_EXTERN void wasm_runtime_set_enlarge_mem_error_callback( - const enlarge_memory_error_callback_t callback); + const enlarge_memory_error_callback_t callback, void *user_data); /* * module instance context APIs From f697244f3354a96ba169445b83a662689cf64231 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Fri, 15 Sep 2023 10:01:08 +0800 Subject: [PATCH 19/58] runtest.py: Show accurate case amount in summary (#2549) Instead of showing the total case amount under *spec/test/core*, show the accurate number of how many test cases were executed. --- .../wamr-test-suites/spec-test-script/all.py | 76 ++++++++++++------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/tests/wamr-test-suites/spec-test-script/all.py b/tests/wamr-test-suites/spec-test-script/all.py index bd5b89ce4..834bb742f 100644 --- a/tests/wamr-test-suites/spec-test-script/all.py +++ b/tests/wamr-test-suites/spec-test-script/all.py @@ -37,6 +37,7 @@ WAST2WASM_CMD = "./wabt/out/gcc/Release/wat2wasm" SPEC_INTERPRETER_CMD = "spec/interpreter/wasm" WAMRC_CMD = "../../../wamr-compiler/build/wamrc" + class TargetAction(argparse.Action): TARGET_MAP = { "ARMV7_VFP": "armv7", @@ -65,7 +66,7 @@ def ignore_the_case( simd_flag=False, gc_flag=False, xip_flag=False, - qemu_flag=False + qemu_flag=False, ): if case_name in ["comments", "inline-module", "names"]: return True @@ -79,7 +80,7 @@ def ignore_the_case( if gc_flag: if case_name in ["type-canon", "type-equivalence", "type-rec"]: - return True; + return True if sgx_flag: if case_name in ["conversions", "f32_bitwise", "f64_bitwise"]: @@ -94,9 +95,20 @@ def ignore_the_case( return True if qemu_flag: - if case_name in ["f32_bitwise", "f64_bitwise", "loop", "f64", "f64_cmp", - "conversions", "f32", "f32_cmp", "float_exprs", - "float_misc", "select", "memory_grow"]: + if case_name in [ + "f32_bitwise", + "f64_bitwise", + "loop", + "f64", + "f64_cmp", + "conversions", + "f32", + "f32_cmp", + "float_exprs", + "float_misc", + "select", + "memory_grow", + ]: return True return False @@ -131,26 +143,9 @@ def test_case( verbose_flag=True, gc_flag=False, qemu_flag=False, - qemu_firmware='', - log='', + qemu_firmware="", + log="", ): - case_path = pathlib.Path(case_path).resolve() - case_name = case_path.stem - - if ignore_the_case( - case_name, - target, - aot_flag, - sgx_flag, - multi_module_flag, - multi_thread_flag, - simd_flag, - gc_flag, - xip_flag, - qemu_flag - ): - return True - CMD = ["python3", "runtest.py"] CMD.append("--wast2wasm") CMD.append(WAST2WASM_CMD if not gc_flag else SPEC_INTERPRETER_CMD) @@ -196,10 +191,13 @@ def test_case( if gc_flag: CMD.append("--gc") - if log != '': + if log != "": CMD.append("--log-dir") CMD.append(log) + case_path = pathlib.Path(case_path).resolve() + case_name = case_path.stem + CMD.append(case_path) print(f"============> run {case_name} ", end="") with subprocess.Popen( @@ -259,8 +257,8 @@ def test_suite( gc_flag=False, parl_flag=False, qemu_flag=False, - qemu_firmware='', - log='', + qemu_firmware="", + log="", ): suite_path = pathlib.Path(SPEC_TEST_DIR).resolve() if not suite_path.exists(): @@ -276,6 +274,26 @@ def test_suite( gc_case_list = sorted(suite_path.glob("gc/*.wast")) case_list.extend(gc_case_list) + # ignore based on command line options + filtered_case_list = [] + for case_path in case_list: + case_name = case_path.stem + if not ignore_the_case( + case_name, + target, + aot_flag, + sgx_flag, + multi_module_flag, + multi_thread_flag, + simd_flag, + gc_flag, + xip_flag, + qemu_flag, + ): + filtered_case_list.append(case_path) + print(f"---> {len(case_list)} --filter--> {len(filtered_case_list)}") + case_list = filtered_case_list + case_count = len(case_list) failed_case = 0 successful_case = 0 @@ -435,7 +453,7 @@ def main(): ) parser.add_argument( "--log", - default='', + default="", dest="log", help="Log directory", ) @@ -512,7 +530,7 @@ def main(): options.gc_flag, options.qemu_flag, options.qemu_firmware, - options.log + options.log, ) else: ret = True From 9c34fc351452dbfb91f9aa7692d6d068a92703bf Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 15 Sep 2023 17:24:12 +0900 Subject: [PATCH 20/58] Fix build with ancient GCC (4.8) (#2553) Fixes: https://github.com/bytecodealliance/wasm-micro-runtime/issues/2552 --- product-mini/platforms/posix/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index d61557022..45237a215 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -497,7 +497,10 @@ dump_pgo_prof_data(wasm_module_inst_t module_inst, const char *path) struct timeout_arg { uint32 timeout_ms; wasm_module_inst_t inst; - _Atomic bool cancel; +#if defined(BH_HAS_STD_ATOMIC) + _Atomic +#endif + bool cancel; }; void * From 132378f30b48b6a61c733c7927fb5701cd3ce86d Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Fri, 15 Sep 2023 12:55:16 +0200 Subject: [PATCH 21/58] Allow using custom signal handler from non-main thread (#2551) Remove thread local attribute of prev_sig_act_SIGSEGV/SIGBUS to allow using custom signal handler from non-main thread since in a thread spawned by embedder, embedder may be unable to call wasm_runtime_init_thread_env to initialize them. And fix the handling of prev_sig_act when its sa_handler is SIG_DFL, SIG_IGN, or a user customized handler. --- core/shared/platform/common/posix/posix_thread.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index 4fb566d6e..b1460f6b5 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -509,8 +509,8 @@ mask_signals(int how) pthread_sigmask(how, &set, NULL); } -static os_thread_local_attribute struct sigaction prev_sig_act_SIGSEGV; -static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS; +static struct sigaction prev_sig_act_SIGSEGV; +static struct sigaction prev_sig_act_SIGBUS; /* ASAN is not designed to work with custom stack unwind or other low-level \ things. > Ignore a function that does some low-level magic. (e.g. walking \ @@ -540,11 +540,16 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext) if (prev_sig_act && (prev_sig_act->sa_flags & SA_SIGINFO)) { prev_sig_act->sa_sigaction(sig_num, sig_info, sig_ucontext); } - else if (prev_sig_act - && ((void *)prev_sig_act->sa_sigaction == SIG_DFL - || (void *)prev_sig_act->sa_sigaction == SIG_IGN)) { + else if (prev_sig_act && (void *)prev_sig_act->sa_handler == SIG_DFL) { + /* Default action */ sigaction(sig_num, prev_sig_act, NULL); } + else if (prev_sig_act && (void *)prev_sig_act->sa_handler == SIG_IGN) { + /* Ignore this signal */ + } + else if (prev_sig_act && prev_sig_act->sa_handler) { + prev_sig_act->sa_handler(sig_num); + } /* Output signal info and then crash if signal is unhandled */ else { switch (sig_num) { From d436e846abd049e1e5125bcb9b7170710387185b Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Sun, 17 Sep 2023 06:54:28 +0100 Subject: [PATCH 22/58] Add support for running tests on apple M1 macs (#2554) --- tests/wamr-test-suites/spec-test-script/all.py | 1 + tests/wamr-test-suites/test_wamr.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/wamr-test-suites/spec-test-script/all.py b/tests/wamr-test-suites/spec-test-script/all.py index 834bb742f..44b0a14bd 100644 --- a/tests/wamr-test-suites/spec-test-script/all.py +++ b/tests/wamr-test-suites/spec-test-script/all.py @@ -50,6 +50,7 @@ class TargetAction(argparse.Action): "THUMBV7_VFP": "thumbv7", "X86_32": "i386", "X86_64": "x86_64", + "AARCH64": "arm64" } def __call__(self, parser, namespace, values, option_string=None): diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 1448e3e1e..f33655207 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -15,7 +15,7 @@ function help() echo "test_wamr.sh [options]" echo "-c clean previous test results, not start test" echo "-s {suite_name} test only one suite (spec|wasi_certification)" - echo "-m set compile target of iwasm(x86_64|x86_32|armv7_vfp|thumbv7_vfp|riscv64_lp64d|riscv64_lp64)" + echo "-m set compile target of iwasm(x86_64|x86_32|armv7_vfp|thumbv7_vfp|riscv64_lp64d|riscv64_lp64|aarch64)" echo "-t set compile type of iwasm(classic-interp|fast-interp|jit|aot|fast-jit|multi-tier-jit)" echo "-M enable multi module feature" echo "-p enable multi thread feature" From 444b1599636e150aa1bc206ec9ad213b624a5ae5 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 20 Sep 2023 19:11:52 +0900 Subject: [PATCH 23/58] Implement async termination of blocking thread (#2516) Send a signal whose handler is no-op to a blocking thread to wake up the blocking syscall with either EINTR equivalent or partial success. Unlike the approach taken in the `dev/interrupt_block_insn` branch (that is, signal + longjmp similarly to `OS_ENABLE_HW_BOUND_CHECK`), this PR does not use longjmp because: * longjmp from signal handler doesn't work on nuttx refer to https://github.com/apache/nuttx/issues/10326 * the singal+longjmp approach may be too difficult for average programmers who might implement host functions to deal with See also https://github.com/bytecodealliance/wasm-micro-runtime/issues/1910 --- build-scripts/config_common.cmake | 7 + core/iwasm/common/wasm_blocking_op.c | 92 ++++ core/iwasm/common/wasm_runtime_common.c | 17 + core/iwasm/common/wasm_runtime_common.h | 9 + core/iwasm/common/wasm_suspend_flags.h | 2 + core/iwasm/include/wasm_export.h | 44 ++ .../libraries/libc-wasi/libc_wasi_wrapper.c | 216 ++++---- .../include/wasmtime_ssp.h | 91 ++++ .../src/blocking_op.c | 201 ++++++++ .../src/blocking_op.h | 52 ++ .../sandboxed-system-primitives/src/posix.c | 461 ++++++++++-------- .../libraries/thread-mgr/thread_manager.c | 4 + .../platform/common/posix/posix_blocking_op.c | 69 +++ .../platform/common/posix/posix_thread.c | 3 + .../platform/darwin/platform_internal.h | 6 + .../platform/freebsd/platform_internal.h | 6 + .../platform/include/platform_api_extension.h | 28 ++ .../shared/platform/linux/platform_internal.h | 6 + .../shared/platform/nuttx/platform_internal.h | 6 + doc/build_wamr.md | 4 + product-mini/platforms/nuttx/wamr.mk | 7 + 21 files changed, 1029 insertions(+), 302 deletions(-) create mode 100644 core/iwasm/common/wasm_blocking_op.c create mode 100644 core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c create mode 100644 core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h create mode 100644 core/shared/platform/common/posix/posix_blocking_op.c diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 0e27e0c09..210f2d788 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -273,6 +273,13 @@ else () add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0) endif () endif () +if (WAMR_DISABLE_WAKEUP_BLOCKING_OP EQUAL 1) + add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=1) + message (" Wakeup of blocking operations disabled") +else () + add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=0) + message (" Wakeup of blocking operations enabled") +endif () if (WAMR_BUILD_SIMD EQUAL 1) if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*") add_definitions (-DWASM_ENABLE_SIMD=1) diff --git a/core/iwasm/common/wasm_blocking_op.c b/core/iwasm/common/wasm_blocking_op.c new file mode 100644 index 000000000..25777c8d7 --- /dev/null +++ b/core/iwasm/common/wasm_blocking_op.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "wasm_runtime_common.h" + +#include "bh_platform.h" +#include "bh_common.h" +#include "bh_assert.h" + +#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP) + +#define LOCK(env) WASM_SUSPEND_FLAGS_LOCK((env)->wait_lock) +#define UNLOCK(env) WASM_SUSPEND_FLAGS_UNLOCK((env)->wait_lock) + +#define ISSET(env, bit) \ + ((WASM_SUSPEND_FLAGS_GET((env)->suspend_flags) & WASM_SUSPEND_FLAG_##bit) \ + != 0) +#define SET(env, bit) \ + WASM_SUSPEND_FLAGS_FETCH_OR((env)->suspend_flags, WASM_SUSPEND_FLAG_##bit) +#define CLR(env, bit) \ + WASM_SUSPEND_FLAGS_FETCH_AND((env)->suspend_flags, ~WASM_SUSPEND_FLAG_##bit) + +bool +wasm_runtime_begin_blocking_op(wasm_exec_env_t env) +{ + LOCK(env); + bh_assert(!ISSET(env, BLOCKING)); + SET(env, BLOCKING); + if (ISSET(env, TERMINATE)) { + CLR(env, BLOCKING); + UNLOCK(env); + return false; + } + UNLOCK(env); + os_begin_blocking_op(); + return true; +} + +void +wasm_runtime_end_blocking_op(wasm_exec_env_t env) +{ + int saved_errno = errno; + LOCK(env); + bh_assert(ISSET(env, BLOCKING)); + CLR(env, BLOCKING); + UNLOCK(env); + os_end_blocking_op(); + errno = saved_errno; +} + +void +wasm_runtime_interrupt_blocking_op(wasm_exec_env_t env) +{ + /* + * ISSET(BLOCKING) here means that the target thread + * is in somewhere between wasm_begin_blocking_op and + * wasm_end_blocking_op. + * keep waking it up until it reaches wasm_end_blocking_op, + * which clears the BLOCKING bit. + * + * this dumb loop is necessary because posix doesn't provide + * a way to unmask signal and block atomically. + */ + + LOCK(env); + SET(env, TERMINATE); + while (ISSET(env, BLOCKING)) { + UNLOCK(env); + os_wakeup_blocking_op(env->handle); + + /* relax a bit */ + os_usleep(50 * 1000); + LOCK(env); + } + UNLOCK(env); +} + +#else /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */ + +bool +wasm_runtime_begin_blocking_op(wasm_exec_env_t env) +{ + return true; +} + +void +wasm_runtime_end_blocking_op(wasm_exec_env_t env) +{} + +#endif /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */ diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 3a2f44c5f..353985b13 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -457,8 +457,21 @@ wasm_runtime_env_init() } #endif +#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP) + if (os_blocking_op_init() != BHT_OK) { + goto fail11; + } + os_end_blocking_op(); +#endif + return true; +#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP) +fail11: +#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 + aot_compiler_destroy(); +#endif +#endif #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 fail10: #if WASM_ENABLE_FAST_JIT != 0 @@ -1392,6 +1405,10 @@ wasm_runtime_init_thread_env(void) } #endif +#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP) + os_end_blocking_op(); +#endif + return true; } diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 4e3bc80af..19d0af117 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -1040,6 +1040,15 @@ WASM_RUNTIME_API_EXTERN bool wasm_runtime_is_import_global_linked(const char *module_name, const char *global_name); +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_begin_blocking_op(WASMExecEnv *exec_env); + +WASM_RUNTIME_API_EXTERN void +wasm_runtime_end_blocking_op(WASMExecEnv *exec_env); + +void +wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/common/wasm_suspend_flags.h b/core/iwasm/common/wasm_suspend_flags.h index b7ecbb0b2..b182b2b5f 100644 --- a/core/iwasm/common/wasm_suspend_flags.h +++ b/core/iwasm/common/wasm_suspend_flags.h @@ -20,6 +20,8 @@ extern "C" { #define WASM_SUSPEND_FLAG_BREAKPOINT 0x4 /* Return from pthread_exit */ #define WASM_SUSPEND_FLAG_EXIT 0x8 +/* The thread might be blocking */ +#define WASM_SUSPEND_FLAG_BLOCKING 0x10 typedef union WASMSuspendFlags { bh_atomic_32_t flags; diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 34206db29..48ed55933 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1546,6 +1546,50 @@ wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key, WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_context(wasm_module_inst_t inst, void *key); +/* + * wasm_runtime_begin_blocking_op/wasm_runtime_end_blocking_op + * + * These APIs are intended to be used by the implementations of + * host functions. It wraps an operation which possibly blocks for long + * to prepare for async termination. + * + * eg. + * + * if (!wasm_runtime_begin_blocking_op(exec_env)) { + * return EINTR; + * } + * ret = possibly_blocking_op(); + * wasm_runtime_end_blocking_op(exec_env); + * return ret; + * + * If threading support (WASM_ENABLE_THREAD_MGR) is not enabled, + * these functions are no-op. + * + * If the underlying platform support (OS_ENABLE_WAKEUP_BLOCKING_OP) is + * not available, these functions are no-op. In that case, the runtime + * might not terminate a blocking thread in a timely manner. + * + * If the underlying platform support is available, it's used to wake up + * the thread for async termination. The expectation here is that a + * `os_wakeup_blocking_op` call makes the blocking operation + * (`possibly_blocking_op` in the above example) return in a timely manner. + * + * The actual wake up mechanism used by `os_wakeup_blocking_op` is + * platform-dependent. It might impose some platform-dependent restrictions + * on the implementation of the blocking opearation. + * + * For example, on POSIX-like platforms, a signal (by default SIGUSR1) is + * used. The signal delivery configurations (eg. signal handler, signal mask, + * etc) for the signal are set up by the runtime. You can change the signal + * to use for this purpose by calling os_set_signal_number_for_blocking_op + * before the runtime initialization. + */ +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env); + +WASM_RUNTIME_API_EXTERN void +wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env); + /* clang-format on */ #ifdef __cplusplus diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index 70ac4dc54..292bd8379 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -335,7 +335,7 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd) if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_close(curfds, prestats, fd); + return wasmtime_ssp_fd_close(exec_env, curfds, prestats, fd); } static wasi_errno_t @@ -348,7 +348,7 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd) if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_datasync(curfds, fd); + return wasmtime_ssp_fd_datasync(exec_env, curfds, fd); } static wasi_errno_t @@ -389,8 +389,8 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app, iovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset, - &nread); + err = wasmtime_ssp_fd_pread(exec_env, curfds, fd, iovec_begin, iovs_len, + offset, &nread); if (err) goto fail; @@ -443,8 +443,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd, ciovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset, - &nwritten); + err = wasmtime_ssp_fd_pwrite(exec_env, curfds, fd, ciovec_begin, iovs_len, + offset, &nwritten); if (err) goto fail; @@ -496,7 +496,8 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread); + err = wasmtime_ssp_fd_read(exec_env, curfds, fd, iovec_begin, iovs_len, + &nread); if (err) goto fail; @@ -521,7 +522,7 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to) if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_renumber(curfds, prestats, from, to); + return wasmtime_ssp_fd_renumber(exec_env, curfds, prestats, from, to); } static wasi_errno_t @@ -538,7 +539,8 @@ wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset, if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset); + return wasmtime_ssp_fd_seek(exec_env, curfds, fd, offset, whence, + newoffset); } static wasi_errno_t @@ -554,7 +556,7 @@ wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset) if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_tell(curfds, fd, newoffset); + return wasmtime_ssp_fd_tell(exec_env, curfds, fd, newoffset); } static wasi_errno_t @@ -573,7 +575,7 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t))) return (wasi_errno_t)-1; - err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat); + err = wasmtime_ssp_fd_fdstat_get(exec_env, curfds, fd, &fdstat); if (err) return err; @@ -592,7 +594,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_fdstat_set_flags(curfds, fd, flags); + return wasmtime_ssp_fd_fdstat_set_flags(exec_env, curfds, fd, flags); } static wasi_errno_t @@ -607,8 +609,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base, - fs_rights_inheriting); + return wasmtime_ssp_fd_fdstat_set_rights( + exec_env, curfds, fd, fs_rights_base, fs_rights_inheriting); } static wasi_errno_t @@ -621,7 +623,7 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd) if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_sync(curfds, fd); + return wasmtime_ssp_fd_sync(exec_env, curfds, fd); } static wasi_errno_t @@ -663,7 +665,8 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd, ciovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten); + err = wasmtime_ssp_fd_write(exec_env, curfds, fd, ciovec_begin, iovs_len, + &nwritten); if (err) goto fail; @@ -688,7 +691,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_advise(curfds, fd, offset, len, advice); + return wasmtime_ssp_fd_advise(exec_env, curfds, fd, offset, len, advice); } static wasi_errno_t @@ -702,7 +705,7 @@ wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_allocate(curfds, fd, offset, len); + return wasmtime_ssp_fd_allocate(exec_env, curfds, fd, offset, len); } static wasi_errno_t @@ -716,7 +719,8 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len); + return wasmtime_ssp_path_create_directory(exec_env, curfds, fd, path, + path_len); } static wasi_errno_t @@ -733,8 +737,9 @@ wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path, - old_path_len, new_fd, new_path, new_path_len); + return wasmtime_ssp_path_link(exec_env, curfds, prestats, old_fd, old_flags, + old_path, old_path_len, new_fd, new_path, + new_path_len); } static wasi_errno_t @@ -756,9 +761,9 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd, if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) return (wasi_errno_t)-1; - err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len, - oflags, fs_rights_base, fs_rights_inheriting, - fs_flags, &fd); + err = wasmtime_ssp_path_open(exec_env, curfds, dirfd, dirflags, path, + path_len, oflags, fs_rights_base, + fs_rights_inheriting, fs_flags, &fd); *fd_app = fd; return err; @@ -780,7 +785,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf, if (!validate_native_addr(bufused_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused); + err = wasmtime_ssp_fd_readdir(exec_env, curfds, fd, buf, buf_len, cookie, + &bufused); if (err) return err; @@ -805,8 +811,8 @@ wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path, if (!validate_native_addr(bufused_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len, - &bufused); + err = wasmtime_ssp_path_readlink(exec_env, curfds, fd, path, path_len, buf, + buf_len, &bufused); if (err) return err; @@ -826,8 +832,9 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len, - new_fd, new_path, new_path_len); + return wasmtime_ssp_path_rename(exec_env, curfds, old_fd, old_path, + old_path_len, new_fd, new_path, + new_path_len); } static wasi_errno_t @@ -844,7 +851,7 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat); + return wasmtime_ssp_fd_filestat_get(exec_env, curfds, fd, filestat); } static wasi_errno_t @@ -859,8 +866,8 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim, - fstflags); + return wasmtime_ssp_fd_filestat_set_times(exec_env, curfds, fd, st_atim, + st_mtim, fstflags); } static wasi_errno_t @@ -874,7 +881,7 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_filestat_set_size(curfds, fd, st_size); + return wasmtime_ssp_fd_filestat_set_size(exec_env, curfds, fd, st_size); } static wasi_errno_t @@ -892,8 +899,8 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len, - filestat); + return wasmtime_ssp_path_filestat_get(exec_env, curfds, fd, flags, path, + path_len, filestat); } static wasi_errno_t @@ -909,8 +916,9 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_filestat_set_times( - curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags); + return wasmtime_ssp_path_filestat_set_times(exec_env, curfds, fd, flags, + path, path_len, st_atim, + st_mtim, fstflags); } static wasi_errno_t @@ -926,8 +934,8 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len, - fd, new_path, new_path_len); + return wasmtime_ssp_path_symlink(exec_env, curfds, prestats, old_path, + old_path_len, fd, new_path, new_path_len); } static wasi_errno_t @@ -941,7 +949,7 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len); + return wasmtime_ssp_path_unlink_file(exec_env, curfds, fd, path, path_len); } static wasi_errno_t @@ -955,7 +963,8 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd, if (!wasi_ctx) return (wasi_errno_t)-1; - return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len); + return wasmtime_ssp_path_remove_directory(exec_env, curfds, fd, path, + path_len); } #if WASM_ENABLE_THREAD_MGR != 0 @@ -1026,8 +1035,8 @@ execute_interruptible_poll_oneoff( /* update timeout for clock subscription events */ update_clock_subscription_data( in_copy, nsubscriptions, min_uint64(time_quant, timeout - elapsed)); - err = wasmtime_ssp_poll_oneoff(curfds, in_copy, out, nsubscriptions, - nevents); + err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in_copy, out, + nsubscriptions, nevents); elapsed += time_quant; if (err) { @@ -1079,7 +1088,8 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in, return (wasi_errno_t)-1; #if WASM_ENABLE_THREAD_MGR == 0 - err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents); + err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in, out, nsubscriptions, + &nevents); #else err = execute_interruptible_poll_oneoff(curfds, in, out, nsubscriptions, &nevents, exec_env); @@ -1133,7 +1143,7 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fdflags_t flags, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_accept(curfds, fd, flags, fd_new); + return wasi_ssp_sock_accept(exec_env, curfds, fd, flags, fd_new); } static wasi_errno_t @@ -1152,7 +1162,7 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_addr_local(curfds, fd, addr); + return wasi_ssp_sock_addr_local(exec_env, curfds, fd, addr); } static wasi_errno_t @@ -1171,7 +1181,7 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_addr_remote(curfds, fd, addr); + return wasi_ssp_sock_addr_remote(exec_env, curfds, fd, addr); } static wasi_errno_t @@ -1192,8 +1202,8 @@ wasi_sock_addr_resolve(wasm_exec_env_t exec_env, const char *host, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx); - return wasi_ssp_sock_addr_resolve(curfds, ns_lookup_list, host, service, - hints, addr_info, addr_info_size, + return wasi_ssp_sock_addr_resolve(exec_env, curfds, ns_lookup_list, host, + service, hints, addr_info, addr_info_size, max_info_size); } @@ -1211,7 +1221,7 @@ wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx); - return wasi_ssp_sock_bind(curfds, addr_pool, fd, addr); + return wasi_ssp_sock_bind(exec_env, curfds, addr_pool, fd, addr); } static wasi_errno_t @@ -1234,7 +1244,7 @@ wasi_sock_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx); - return wasi_ssp_sock_connect(curfds, addr_pool, fd, addr); + return wasi_ssp_sock_connect(exec_env, curfds, addr_pool, fd, addr); } static wasi_errno_t @@ -1253,7 +1263,7 @@ wasi_sock_get_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_broadcast(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_broadcast(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1272,7 +1282,7 @@ wasi_sock_get_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_keep_alive(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_keep_alive(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1292,7 +1302,8 @@ wasi_sock_get_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool *is_enabled, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_linger(curfds, fd, is_enabled, linger_s); + return wasmtime_ssp_sock_get_linger(exec_env, curfds, fd, is_enabled, + linger_s); } static wasi_errno_t @@ -1311,7 +1322,7 @@ wasi_sock_get_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_recv_buf_size(curfds, fd, size); + return wasmtime_ssp_sock_get_recv_buf_size(exec_env, curfds, fd, size); } static wasi_errno_t @@ -1330,7 +1341,7 @@ wasi_sock_get_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_recv_timeout(curfds, fd, timeout_us); + return wasmtime_ssp_sock_get_recv_timeout(exec_env, curfds, fd, timeout_us); } static wasi_errno_t @@ -1349,7 +1360,7 @@ wasi_sock_get_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_reuse_addr(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_reuse_addr(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1368,7 +1379,7 @@ wasi_sock_get_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_reuse_port(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_reuse_port(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1387,7 +1398,7 @@ wasi_sock_get_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_send_buf_size(curfds, fd, size); + return wasmtime_ssp_sock_get_send_buf_size(exec_env, curfds, fd, size); } static wasi_errno_t @@ -1406,7 +1417,7 @@ wasi_sock_get_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_send_timeout(curfds, fd, timeout_us); + return wasmtime_ssp_sock_get_send_timeout(exec_env, curfds, fd, timeout_us); } static wasi_errno_t @@ -1425,7 +1436,8 @@ wasi_sock_get_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_tcp_fastopen_connect(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_tcp_fastopen_connect(exec_env, curfds, fd, + is_enabled); } static wasi_errno_t @@ -1444,7 +1456,7 @@ wasi_sock_get_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_tcp_no_delay(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_tcp_no_delay(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1463,7 +1475,8 @@ wasi_sock_get_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_tcp_quick_ack(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_tcp_quick_ack(exec_env, curfds, fd, + is_enabled); } static wasi_errno_t @@ -1482,7 +1495,7 @@ wasi_sock_get_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_tcp_keep_idle(curfds, fd, time_s); + return wasmtime_ssp_sock_get_tcp_keep_idle(exec_env, curfds, fd, time_s); } static wasi_errno_t @@ -1501,7 +1514,7 @@ wasi_sock_get_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_tcp_keep_intvl(curfds, fd, time_s); + return wasmtime_ssp_sock_get_tcp_keep_intvl(exec_env, curfds, fd, time_s); } static wasi_errno_t @@ -1520,7 +1533,7 @@ wasi_sock_get_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_ip_multicast_loop(curfds, fd, ipv6, + return wasmtime_ssp_sock_get_ip_multicast_loop(exec_env, curfds, fd, ipv6, is_enabled); } @@ -1539,7 +1552,7 @@ wasi_sock_get_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t *ttl_s) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_ip_ttl(curfds, fd, ttl_s); + return wasmtime_ssp_sock_get_ip_ttl(exec_env, curfds, fd, ttl_s); } static wasi_errno_t @@ -1558,7 +1571,7 @@ wasi_sock_get_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_ip_multicast_ttl(curfds, fd, ttl_s); + return wasmtime_ssp_sock_get_ip_multicast_ttl(exec_env, curfds, fd, ttl_s); } static wasi_errno_t @@ -1577,7 +1590,7 @@ wasi_sock_get_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_get_ipv6_only(curfds, fd, is_enabled); + return wasmtime_ssp_sock_get_ipv6_only(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1592,7 +1605,7 @@ wasi_sock_listen(wasm_exec_env_t exec_env, wasi_fd_t fd, uint32 backlog) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_listen(curfds, fd, backlog); + return wasi_ssp_sock_listen(exec_env, curfds, fd, backlog); } static wasi_errno_t @@ -1609,7 +1622,7 @@ wasi_sock_open(wasm_exec_env_t exec_env, wasi_fd_t poolfd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_open(curfds, poolfd, af, socktype, sockfd); + return wasi_ssp_sock_open(exec_env, curfds, poolfd, af, socktype, sockfd); } static wasi_errno_t @@ -1624,7 +1637,7 @@ wasi_sock_set_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_broadcast(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_broadcast(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1640,7 +1653,7 @@ wasi_sock_set_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_keep_alive(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_keep_alive(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1656,7 +1669,8 @@ wasi_sock_set_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_linger(curfds, fd, is_enabled, linger_s); + return wasmtime_ssp_sock_set_linger(exec_env, curfds, fd, is_enabled, + linger_s); } static wasi_errno_t @@ -1671,7 +1685,7 @@ wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_recv_buf_size(curfds, fd, size); + return wasmtime_ssp_sock_set_recv_buf_size(exec_env, curfds, fd, size); } static wasi_errno_t @@ -1687,7 +1701,7 @@ wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, timeout_us); + return wasmtime_ssp_sock_set_recv_timeout(exec_env, curfds, fd, timeout_us); } static wasi_errno_t @@ -1703,7 +1717,7 @@ wasi_sock_set_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_reuse_addr(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_reuse_addr(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1719,7 +1733,7 @@ wasi_sock_set_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_reuse_port(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_reuse_port(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1734,7 +1748,7 @@ wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_send_buf_size(curfds, fd, size); + return wasmtime_ssp_sock_set_send_buf_size(exec_env, curfds, fd, size); } static wasi_errno_t @@ -1750,7 +1764,7 @@ wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_send_timeout(curfds, fd, timeout_us); + return wasmtime_ssp_sock_set_send_timeout(exec_env, curfds, fd, timeout_us); } static wasi_errno_t @@ -1766,7 +1780,8 @@ wasi_sock_set_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_tcp_fastopen_connect(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_tcp_fastopen_connect(exec_env, curfds, fd, + is_enabled); } static wasi_errno_t @@ -1782,7 +1797,7 @@ wasi_sock_set_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_tcp_no_delay(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_tcp_no_delay(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -1798,7 +1813,8 @@ wasi_sock_set_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_tcp_quick_ack(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_tcp_quick_ack(exec_env, curfds, fd, + is_enabled); } static wasi_errno_t @@ -1814,7 +1830,7 @@ wasi_sock_set_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_tcp_keep_idle(curfds, fd, time_s); + return wasmtime_ssp_sock_set_tcp_keep_idle(exec_env, curfds, fd, time_s); } static wasi_errno_t @@ -1830,7 +1846,7 @@ wasi_sock_set_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_tcp_keep_intvl(curfds, fd, time_s); + return wasmtime_ssp_sock_set_tcp_keep_intvl(exec_env, curfds, fd, time_s); } static wasi_errno_t @@ -1846,7 +1862,7 @@ wasi_sock_set_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ip_multicast_loop(curfds, fd, ipv6, + return wasmtime_ssp_sock_set_ip_multicast_loop(exec_env, curfds, fd, ipv6, is_enabled); } @@ -1867,8 +1883,8 @@ wasi_sock_set_ip_add_membership(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ip_add_membership(curfds, fd, imr_multiaddr, - imr_interface); + return wasmtime_ssp_sock_set_ip_add_membership( + exec_env, curfds, fd, imr_multiaddr, imr_interface); } static wasi_errno_t @@ -1888,8 +1904,8 @@ wasi_sock_set_ip_drop_membership(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ip_drop_membership(curfds, fd, imr_multiaddr, - imr_interface); + return wasmtime_ssp_sock_set_ip_drop_membership( + exec_env, curfds, fd, imr_multiaddr, imr_interface); } static wasi_errno_t @@ -1904,7 +1920,7 @@ wasi_sock_set_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t ttl_s) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ip_ttl(curfds, fd, ttl_s); + return wasmtime_ssp_sock_set_ip_ttl(exec_env, curfds, fd, ttl_s); } static wasi_errno_t @@ -1920,7 +1936,7 @@ wasi_sock_set_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ip_multicast_ttl(curfds, fd, ttl_s); + return wasmtime_ssp_sock_set_ip_multicast_ttl(exec_env, curfds, fd, ttl_s); } static wasi_errno_t @@ -1935,7 +1951,7 @@ wasi_sock_set_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled) curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_set_ipv6_only(curfds, fd, is_enabled); + return wasmtime_ssp_sock_set_ipv6_only(exec_env, curfds, fd, is_enabled); } static wasi_errno_t @@ -2053,8 +2069,9 @@ wasi_sock_recv_from(wasm_exec_env_t exec_env, wasi_fd_t sock, memset(buf_begin, 0, total_size); *ro_data_len = 0; - err = wasmtime_ssp_sock_recv_from(curfds, sock, buf_begin, total_size, - ri_flags, src_addr, &recv_bytes); + err = wasmtime_ssp_sock_recv_from(exec_env, curfds, sock, buf_begin, + total_size, ri_flags, src_addr, + &recv_bytes); if (err != __WASI_ESUCCESS) { goto fail; } @@ -2153,7 +2170,8 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock, return err; *so_data_len = 0; - err = wasmtime_ssp_sock_send(curfds, sock, buf, buf_size, &send_bytes); + err = wasmtime_ssp_sock_send(exec_env, curfds, sock, buf, buf_size, + &send_bytes); *so_data_len = (uint32)send_bytes; wasm_runtime_free(buf); @@ -2193,8 +2211,8 @@ wasi_sock_send_to(wasm_exec_env_t exec_env, wasi_fd_t sock, return err; *so_data_len = 0; - err = wasmtime_ssp_sock_send_to(curfds, addr_pool, sock, buf, buf_size, - si_flags, dest_addr, &send_bytes); + err = wasmtime_ssp_sock_send_to(exec_env, curfds, addr_pool, sock, buf, + buf_size, si_flags, dest_addr, &send_bytes); *so_data_len = (uint32)send_bytes; wasm_runtime_free(buf); @@ -2212,7 +2230,7 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how) if (!wasi_ctx) return __WASI_EINVAL; - return wasmtime_ssp_sock_shutdown(curfds, sock); + return wasmtime_ssp_sock_shutdown(exec_env, curfds, sock); } static wasi_errno_t diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h index a53153552..efe7c8e3a 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h @@ -22,6 +22,8 @@ #include #include +#include "wasm_export.h" + /* clang-format off */ #ifdef __cplusplus @@ -646,17 +648,20 @@ __wasi_errno_t wasmtime_ssp_fd_prestat_dir_name( ) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_close( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_datasync( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_pread( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const __wasi_iovec_t *iovs, @@ -666,6 +671,7 @@ __wasi_errno_t wasmtime_ssp_fd_pread( ) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_pwrite( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const __wasi_ciovec_t *iovs, @@ -675,6 +681,7 @@ __wasi_errno_t wasmtime_ssp_fd_pwrite( ) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_read( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const __wasi_iovec_t *iovs, @@ -683,6 +690,7 @@ __wasi_errno_t wasmtime_ssp_fd_read( ) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_renumber( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, __wasi_fd_t from, @@ -690,6 +698,7 @@ __wasi_errno_t wasmtime_ssp_fd_renumber( ) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_seek( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filedelta_t offset, @@ -698,24 +707,28 @@ __wasi_errno_t wasmtime_ssp_fd_seek( ) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_tell( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filesize_t *newoffset ) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_get( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_fdstat_t *buf ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_fdflags_t flags ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_rights_t fs_rights_base, @@ -723,11 +736,13 @@ __wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights( ) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_sync( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd ) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_write( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const __wasi_ciovec_t *iovs, @@ -736,6 +751,7 @@ __wasi_errno_t wasmtime_ssp_fd_write( ) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_advise( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filesize_t offset, @@ -744,6 +760,7 @@ __wasi_errno_t wasmtime_ssp_fd_advise( ) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_allocate( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filesize_t offset, @@ -751,6 +768,7 @@ __wasi_errno_t wasmtime_ssp_fd_allocate( ) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_create_directory( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const char *path, @@ -758,6 +776,7 @@ __wasi_errno_t wasmtime_ssp_path_create_directory( ) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_link( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, __wasi_fd_t old_fd, @@ -770,6 +789,7 @@ __wasi_errno_t wasmtime_ssp_path_link( ) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_open( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t dirfd, __wasi_lookupflags_t dirflags, @@ -783,6 +803,7 @@ __wasi_errno_t wasmtime_ssp_path_open( ) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_readdir( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, void *buf, @@ -792,6 +813,7 @@ __wasi_errno_t wasmtime_ssp_fd_readdir( ) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_readlink( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const char *path, @@ -802,6 +824,7 @@ __wasi_errno_t wasmtime_ssp_path_readlink( ) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_rename( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t old_fd, const char *old_path, @@ -812,12 +835,14 @@ __wasi_errno_t wasmtime_ssp_path_rename( ) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_get( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filestat_t *buf ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_set_times( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_timestamp_t st_atim, @@ -826,12 +851,14 @@ __wasi_errno_t wasmtime_ssp_fd_filestat_set_times( ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_fd_filestat_set_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_filesize_t st_size ) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_filestat_get( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_lookupflags_t flags, @@ -841,6 +868,7 @@ __wasi_errno_t wasmtime_ssp_path_filestat_get( ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_filestat_set_times( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_lookupflags_t flags, @@ -852,6 +880,7 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times( ) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_symlink( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, const char *old_path, @@ -862,6 +891,7 @@ __wasi_errno_t wasmtime_ssp_path_symlink( ) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_unlink_file( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const char *path, @@ -869,6 +899,7 @@ __wasi_errno_t wasmtime_ssp_path_unlink_file( ) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_path_remove_directory( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, const char *path, @@ -876,6 +907,7 @@ __wasi_errno_t wasmtime_ssp_path_remove_directory( ) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_poll_oneoff( + wasm_exec_env_t exec_env, struct fd_table *curfds, const __wasi_subscription_t *in, __wasi_event_t *out, @@ -890,24 +922,28 @@ __wasi_errno_t wasmtime_ssp_random_get( __wasi_errno_t wasi_ssp_sock_accept( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_local( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_remote( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_open( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype, __wasi_fd_t *sockfd @@ -915,12 +951,14 @@ wasi_ssp_sock_open( __wasi_errno_t wasi_ssp_sock_bind( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct addr_pool *addr_pool, __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_addr_resolve( + wasm_exec_env_t exec_env, struct fd_table *curfds, char **ns_lookup_list, const char *host, const char* service, __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info, @@ -929,65 +967,76 @@ wasi_ssp_sock_addr_resolve( __wasi_errno_t wasi_ssp_sock_connect( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct addr_pool *addr_pool, __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_recv_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t *size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_reuse_addr( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, uint8_t *reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_reuse_port( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, uint8_t *reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_get_send_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t *size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_recv_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_reuse_addr( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, uint8_t reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_reuse_port( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, uint8_t reuse ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_set_send_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t size ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasi_ssp_sock_listen( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t backlog ) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_recv( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, void *buf, @@ -996,6 +1045,7 @@ __wasi_errno_t wasmtime_ssp_sock_recv( ) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_recv_from( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, void *buf, @@ -1006,6 +1056,7 @@ __wasi_errno_t wasmtime_ssp_sock_recv_from( ) WASMTIME_SSP_SYSCALL_NAME(sock_recv_from) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_send( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, const void *buf, @@ -1014,6 +1065,7 @@ __wasi_errno_t wasmtime_ssp_sock_send( ) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_send_to( + wasm_exec_env_t exec_env, struct fd_table *curfds, struct addr_pool *addr_pool, __wasi_fd_t sock, const void *buf, @@ -1024,53 +1076,62 @@ __wasi_errno_t wasmtime_ssp_sock_send_to( ) WASMTIME_SSP_SYSCALL_NAME(sock_send_to) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_shutdown( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock ) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_recv_timeout( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint64_t timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_recv_timeout( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint64_t *timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_send_timeout( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint64_t timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_send_timeout( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint64_t *timeout_us ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_timeout) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_send_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, size_t bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_send_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, size_t *bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_recv_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, size_t bufsiz ) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_buf_size) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, size_t *bufsiz @@ -1078,42 +1139,49 @@ __wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size( __wasi_errno_t wasmtime_ssp_sock_set_keep_alive( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_keep_alive) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_keep_alive( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_keep_alive) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_reuse_addr( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_addr) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_reuse_addr( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_addr) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_reuse_port( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_port) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_reuse_port( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_port) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_linger( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled, @@ -1121,83 +1189,97 @@ __wasi_errno_t wasmtime_ssp_sock_set_linger( ) WASMTIME_SSP_SYSCALL_NAME(sock_set_linger) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_linger( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled, int *linger_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_linger) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_broadcast( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_broadcast) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_broadcast( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_broadcast) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_no_delay( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_no_delay) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_no_delay( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_no_delay) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_quick_ack( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_quick_ack) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_quick_ack( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_quick_ack) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_idle( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint32_t time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_idle) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_idle( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint32_t *time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_idle) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_intvl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint32_t time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_intvl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_intvl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint32_t *time_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_intvl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_tcp_fastopen_connect( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_tcp_fastopen_connect( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_fastopen_connect) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool ipv6, @@ -1205,6 +1287,7 @@ __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop( ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_loop) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool ipv6, @@ -1212,6 +1295,7 @@ __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop( ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_loop) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, @@ -1219,6 +1303,7 @@ __wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership( ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_add_membership) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, @@ -1226,36 +1311,42 @@ __wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership( ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_drop_membership) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_ttl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint8_t ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_ttl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint8_t *ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_ttl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint8_t ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_ttl( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, uint8_t *ttl_s ) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_ttl) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_set_ipv6_only( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool is_enabled ) WASMTIME_SSP_SYSCALL_NAME(sock_set_ipv6_only) __attribute__((__warn_unused_result__)); __wasi_errno_t wasmtime_ssp_sock_get_ipv6_only( + wasm_exec_env_t exec_env, struct fd_table *curfds, __wasi_fd_t sock, bool *is_enabled diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c new file mode 100644 index 000000000..9d01f2bfe --- /dev/null +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +#include "ssp_config.h" +#include "blocking_op.h" + +int +blocking_op_close(wasm_exec_env_t exec_env, int fd) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = close(fd); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +ssize_t +blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = readv(fd, iov, iovcnt); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +#if CONFIG_HAS_PREADV +ssize_t +blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt, off_t offset) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = preadv(fd, iov, iovcnt, offset); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} +#else /* CONFIG_HAS_PREADV */ +ssize_t +blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb, + off_t offset) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = pread(fd, p, nb, offset); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} +#endif /* CONFIG_HAS_PREADV */ + +ssize_t +blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = writev(fd, iov, iovcnt); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +#if CONFIG_HAS_PWRITEV +ssize_t +blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt, off_t offset) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = pwritev(fd, iov, iovcnt, offset); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} +#else /* CONFIG_HAS_PWRITEV */ +ssize_t +blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb, + off_t offset) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + ssize_t ret = pwrite(fd, p, nb, offset); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} +#endif /* CONFIG_HAS_PWRITEV */ + +int +blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock, + bh_socket_t *sockp, void *addr, + unsigned int *addrlenp) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = os_socket_accept(server_sock, sockp, addr, addrlenp); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +int +blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock, + const char *addr, int port) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = os_socket_connect(sock, addr, port); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +int +blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock, + void *buf, unsigned int len, int flags, + bh_sockaddr_t *src_addr) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = os_socket_recv_from(sock, buf, len, flags, src_addr); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +int +blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock, + const void *buf, unsigned int len, int flags, + const bh_sockaddr_t *dest_addr) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = os_socket_send_to(sock, buf, len, flags, dest_addr); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +int +blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host, + const char *service, uint8_t *hint_is_tcp, + uint8_t *hint_is_ipv4, + bh_addr_info_t *addr_info, + size_t addr_info_size, size_t *max_info_size) +{ + /* + * Note: Unlike others, os_socket_addr_resolve() is not a simple system + * call. It's likely backed by a complex libc function, getaddrinfo(). + * Depending on the implementation of getaddrinfo() and underlying + * DNS resolver, it might or might not be possible to make it return + * with os_wakeup_blocking_op(). + * + * Unfortunately, many of ISC/bind based resolvers just keep going on + * interrupted system calls. It includes macOS and glibc. + * + * On the other hand, NuttX as of writing this returns EAI_AGAIN + * on EINTR. + */ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = os_socket_addr_resolve(host, service, hint_is_tcp, hint_is_ipv4, + addr_info, addr_info_size, max_info_size); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} + +int +blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path, + int oflags, mode_t mode) +{ + if (!wasm_runtime_begin_blocking_op(exec_env)) { + errno = EINTR; + return -1; + } + int ret = openat(fd, path, oflags, mode); + wasm_runtime_end_blocking_op(exec_env); + return ret; +} diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h new file mode 100644 index 000000000..44a16d338 --- /dev/null +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "bh_platform.h" +#include "wasm_export.h" + +int +blocking_op_close(wasm_exec_env_t exec_env, int fd); +ssize_t +blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt); +ssize_t +blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt, off_t offset); +ssize_t +blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb, + off_t offset); +ssize_t +blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt); +ssize_t +blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov, + int iovcnt, off_t offset); +ssize_t +blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb, + off_t offset); +int +blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock, + bh_socket_t *sockp, void *addr, + unsigned int *addrlenp); +int +blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock, + const char *addr, int port); +int +blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock, + void *buf, unsigned int len, int flags, + bh_sockaddr_t *src_addr); +int +blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock, + const void *buf, unsigned int len, int flags, + const bh_sockaddr_t *dest_addr); +int +blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host, + const char *service, uint8_t *hint_is_tcp, + uint8_t *hint_is_ipv4, + bh_addr_info_t *addr_info, + size_t addr_info_size, size_t *max_info_size); +int +blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path, + int oflags, mode_t mode); diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index a9831d770..c096511c9 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -13,6 +13,7 @@ #include "ssp_config.h" #include "bh_platform.h" +#include "blocking_op.h" #include "wasmtime_ssp.h" #include "locking.h" #include "posix.h" @@ -630,16 +631,25 @@ fd_number(const struct fd_object *fo) return number; } -#define CLOSE_NON_STD_FD(fd) \ - do { \ - if (fd > 2) \ - close(fd); \ +// The env == NULL case is for +// fd_table_destroy, path_get, path_put, fd_table_insert_existing +#define CLOSE_NON_STD_FD(env, fd) \ + do { \ + if (fd > 2) { \ + if (env == NULL) { \ + close(fd); \ + } \ + else { \ + blocking_op_close(env, fd); \ + } \ + } \ } while (0) // Lowers the reference count on a file descriptor object. When the // reference count reaches zero, its resources are cleaned up. static void -fd_object_release(struct fd_object *fo) UNLOCKS(fo->refcount) +fd_object_release(wasm_exec_env_t env, struct fd_object *fo) + UNLOCKS(fo->refcount) { if (refcount_release(&fo->refcount)) { int saved_errno = errno; @@ -649,14 +659,14 @@ fd_object_release(struct fd_object *fo) UNLOCKS(fo->refcount) // closedir() on it also closes the underlying file descriptor. mutex_destroy(&fo->directory.lock); if (fo->directory.handle == NULL) { - CLOSE_NON_STD_FD(fd_number(fo)); + CLOSE_NON_STD_FD(env, fd_number(fo)); } else { closedir(fo->directory.handle); } break; default: - CLOSE_NON_STD_FD(fd_number(fo)); + CLOSE_NON_STD_FD(env, fd_number(fo)); break; } wasm_runtime_free(fo); @@ -695,7 +705,7 @@ fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in, int out) fo->number = out; if (type == __WASI_FILETYPE_DIRECTORY) { if (!mutex_init(&fo->directory.lock)) { - fd_object_release(fo); + fd_object_release(NULL, fo); return false; } fo->directory.handle = NULL; @@ -705,7 +715,7 @@ fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in, int out) rwlock_wrlock(&ft->lock); if (!fd_table_grow(ft, in, 1)) { rwlock_unlock(&ft->lock); - fd_object_release(fo); + fd_object_release(NULL, fo); return false; } @@ -729,16 +739,16 @@ fd_table_unused(struct fd_table *ft) REQUIRES_SHARED(ft->lock) // Inserts a file descriptor object into an unused slot of the file // descriptor table. static __wasi_errno_t -fd_table_insert(struct fd_table *ft, struct fd_object *fo, - __wasi_rights_t rights_base, __wasi_rights_t rights_inheriting, - __wasi_fd_t *out) REQUIRES_UNLOCKED(ft->lock) - UNLOCKS(fo->refcount) +fd_table_insert(wasm_exec_env_t exec_env, struct fd_table *ft, + struct fd_object *fo, __wasi_rights_t rights_base, + __wasi_rights_t rights_inheriting, __wasi_fd_t *out) + REQUIRES_UNLOCKED(ft->lock) UNLOCKS(fo->refcount) { // Grow the file descriptor table if needed. rwlock_wrlock(&ft->lock); if (!fd_table_grow(ft, 0, 1)) { rwlock_unlock(&ft->lock); - fd_object_release(fo); + fd_object_release(exec_env, fo); return convert_errno(errno); } @@ -750,8 +760,8 @@ fd_table_insert(struct fd_table *ft, struct fd_object *fo, // Inserts a numerical file descriptor into the file descriptor table. static __wasi_errno_t -fd_table_insert_fd(struct fd_table *ft, int in, __wasi_filetype_t type, - __wasi_rights_t rights_base, +fd_table_insert_fd(wasm_exec_env_t exec_env, struct fd_table *ft, int in, + __wasi_filetype_t type, __wasi_rights_t rights_base, __wasi_rights_t rights_inheriting, __wasi_fd_t *out) REQUIRES_UNLOCKED(ft->lock) { @@ -766,12 +776,13 @@ fd_table_insert_fd(struct fd_table *ft, int in, __wasi_filetype_t type, fo->number = in; if (type == __WASI_FILETYPE_DIRECTORY) { if (!mutex_init(&fo->directory.lock)) { - fd_object_release(fo); + fd_object_release(exec_env, fo); return (__wasi_errno_t)-1; } fo->directory.handle = NULL; } - return fd_table_insert(ft, fo, rights_base, rights_inheriting, out); + return fd_table_insert(exec_env, ft, fo, rights_base, rights_inheriting, + out); } __wasi_errno_t @@ -821,8 +832,8 @@ wasmtime_ssp_fd_prestat_dir_name(struct fd_prestats *prestats, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_close(struct fd_table *curfds, struct fd_prestats *prestats, - __wasi_fd_t fd) +wasmtime_ssp_fd_close(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct fd_prestats *prestats, __wasi_fd_t fd) { // Don't allow closing a pre-opened resource. // TODO: Eventually, we do want to permit this, once libpreopen in @@ -851,7 +862,7 @@ wasmtime_ssp_fd_close(struct fd_table *curfds, struct fd_prestats *prestats, struct fd_object *fo; fd_table_detach(ft, fd, &fo); rwlock_unlock(&ft->lock); - fd_object_release(fo); + fd_object_release(exec_env, fo); return 0; } @@ -894,7 +905,8 @@ fd_object_get(struct fd_table *curfds, struct fd_object **fo, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_datasync(struct fd_table *curfds, __wasi_fd_t fd) +wasmtime_ssp_fd_datasync(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd) { struct fd_object *fo; __wasi_errno_t error = @@ -907,15 +919,15 @@ wasmtime_ssp_fd_datasync(struct fd_table *curfds, __wasi_fd_t fd) #else int ret = fsync(fd_number(fo)); #endif - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; } __wasi_errno_t -wasmtime_ssp_fd_pread(struct fd_table *curfds, __wasi_fd_t fd, - const __wasi_iovec_t *iov, size_t iovcnt, +wasmtime_ssp_fd_pread(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const __wasi_iovec_t *iov, size_t iovcnt, __wasi_filesize_t offset, size_t *nread) { if (iovcnt == 0) @@ -928,17 +940,19 @@ wasmtime_ssp_fd_pread(struct fd_table *curfds, __wasi_fd_t fd, return error; #if CONFIG_HAS_PREADV - ssize_t len = preadv(fd_number(fo), (const struct iovec *)iov, (int)iovcnt, - (off_t)offset); - fd_object_release(fo); + ssize_t len = + blocking_op_preadv(exec_env, fd_number(fo), (const struct iovec *)iov, + (int)iovcnt, (off_t)offset); + fd_object_release(exec_env, fo); if (len < 0) return convert_errno(errno); *nread = (size_t)len; return 0; #else if (iovcnt == 1) { - ssize_t len = pread(fd_number(fo), iov->buf, iov->buf_len, offset); - fd_object_release(fo); + ssize_t len = blocking_op_pread(exec_env, fd_number(fo), iov->buf, + iov->buf_len, offset); + fd_object_release(exec_env, fo); if (len < 0) return convert_errno(errno); *nread = len; @@ -951,13 +965,14 @@ wasmtime_ssp_fd_pread(struct fd_table *curfds, __wasi_fd_t fd, totalsize += iov[i].buf_len; char *buf = wasm_runtime_malloc(totalsize); if (buf == NULL) { - fd_object_release(fo); + fd_object_release(exec_env, fo); return __WASI_ENOMEM; } // Perform a single read operation. - ssize_t len = pread(fd_number(fo), buf, totalsize, offset); - fd_object_release(fo); + ssize_t len = + blocking_op_pread(exec_env, fd_number(fo), buf, totalsize, offset); + fd_object_release(exec_env, fo); if (len < 0) { wasm_runtime_free(buf); return convert_errno(errno); @@ -985,9 +1000,10 @@ wasmtime_ssp_fd_pread(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, - const __wasi_ciovec_t *iov, size_t iovcnt, - __wasi_filesize_t offset, size_t *nwritten) +wasmtime_ssp_fd_pwrite(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const __wasi_ciovec_t *iov, + size_t iovcnt, __wasi_filesize_t offset, + size_t *nwritten) { if (iovcnt == 0) return __WASI_EINVAL; @@ -1000,11 +1016,13 @@ wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, ssize_t len; #if CONFIG_HAS_PWRITEV - len = pwritev(fd_number(fo), (const struct iovec *)iov, (int)iovcnt, - (off_t)offset); + len = + blocking_op_pwritev(exec_env, fd_number(fo), (const struct iovec *)iov, + (int)iovcnt, (off_t)offset); #else if (iovcnt == 1) { - len = pwrite(fd_number(fo), iov->buf, iov->buf_len, offset); + len = blocking_op_pwrite(exec_env, fd_number(fo), iov->buf, + iov->buf_len, offset); } else { // Allocate a single buffer to fit all data. @@ -1013,7 +1031,7 @@ wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, totalsize += iov[i].buf_len; char *buf = wasm_runtime_malloc(totalsize); if (buf == NULL) { - fd_object_release(fo); + fd_object_release(exec_env, fo); return __WASI_ENOMEM; } size_t bufoff = 0; @@ -1024,11 +1042,12 @@ wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, } // Perform a single write operation. - len = pwrite(fd_number(fo), buf, totalsize, offset); + len = + blocking_op_pwrite(exec_env, fd_number(fo), buf, totalsize, offset); wasm_runtime_free(buf); } #endif - fd_object_release(fo); + fd_object_release(exec_env, fo); if (len < 0) return convert_errno(errno); *nwritten = (size_t)len; @@ -1036,8 +1055,9 @@ wasmtime_ssp_fd_pwrite(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_read(struct fd_table *curfds, __wasi_fd_t fd, - const __wasi_iovec_t *iov, size_t iovcnt, size_t *nread) +wasmtime_ssp_fd_read(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const __wasi_iovec_t *iov, size_t iovcnt, + size_t *nread) { struct fd_object *fo; __wasi_errno_t error = @@ -1045,8 +1065,9 @@ wasmtime_ssp_fd_read(struct fd_table *curfds, __wasi_fd_t fd, if (error != 0) return error; - ssize_t len = readv(fd_number(fo), (const struct iovec *)iov, (int)iovcnt); - fd_object_release(fo); + ssize_t len = blocking_op_readv(exec_env, fd_number(fo), + (const struct iovec *)iov, (int)iovcnt); + fd_object_release(exec_env, fo); if (len < 0) return convert_errno(errno); *nread = (size_t)len; @@ -1054,8 +1075,9 @@ wasmtime_ssp_fd_read(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats, - __wasi_fd_t from, __wasi_fd_t to) +wasmtime_ssp_fd_renumber(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct fd_prestats *prestats, __wasi_fd_t from, + __wasi_fd_t to) { // Don't allow renumbering over a pre-opened resource. // TODO: Eventually, we do want to permit this, once libpreopen in @@ -1093,11 +1115,11 @@ wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats, refcount_acquire(&fe_from->object->refcount); fd_table_attach(ft, to, fe_from->object, fe_from->rights_base, fe_from->rights_inheriting); - fd_object_release(fo); + fd_object_release(exec_env, fo); // Remove the old fd from the file descriptor table. fd_table_detach(ft, from, &fo); - fd_object_release(fo); + fd_object_release(exec_env, fo); --ft->used; rwlock_unlock(&ft->lock); @@ -1105,9 +1127,9 @@ wasmtime_ssp_fd_renumber(struct fd_table *curfds, struct fd_prestats *prestats, } __wasi_errno_t -wasmtime_ssp_fd_seek(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_filedelta_t offset, __wasi_whence_t whence, - __wasi_filesize_t *newoffset) +wasmtime_ssp_fd_seek(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_filedelta_t offset, + __wasi_whence_t whence, __wasi_filesize_t *newoffset) { int nwhence; switch (whence) { @@ -1135,7 +1157,7 @@ wasmtime_ssp_fd_seek(struct fd_table *curfds, __wasi_fd_t fd, return error; off_t ret = lseek(fd_number(fo), offset, nwhence); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); *newoffset = (__wasi_filesize_t)ret; @@ -1143,8 +1165,8 @@ wasmtime_ssp_fd_seek(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_tell(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_filesize_t *newoffset) +wasmtime_ssp_fd_tell(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_filesize_t *newoffset) { struct fd_object *fo; __wasi_errno_t error = @@ -1153,7 +1175,7 @@ wasmtime_ssp_fd_tell(struct fd_table *curfds, __wasi_fd_t fd, return error; off_t ret = lseek(fd_number(fo), 0, SEEK_CUR); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); *newoffset = (__wasi_filesize_t)ret; @@ -1161,8 +1183,8 @@ wasmtime_ssp_fd_tell(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_fdstat_get(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_fdstat_t *buf) +wasmtime_ssp_fd_fdstat_get(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_fdstat_t *buf) { struct fd_table *ft = curfds; rwlock_rdlock(&ft->lock); @@ -1210,7 +1232,8 @@ wasmtime_ssp_fd_fdstat_get(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_fdstat_set_flags(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_fd_fdstat_set_flags(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_fdflags_t fs_flags) { int noflags = 0; @@ -1240,14 +1263,15 @@ wasmtime_ssp_fd_fdstat_set_flags(struct fd_table *curfds, __wasi_fd_t fd, return error; int ret = fcntl(fd_number(fo), F_SETFL, noflags); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; } __wasi_errno_t -wasmtime_ssp_fd_fdstat_set_rights(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_fd_fdstat_set_rights(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_rights_t fs_rights_base, __wasi_rights_t fs_rights_inheriting) { @@ -1269,7 +1293,8 @@ wasmtime_ssp_fd_fdstat_set_rights(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_sync(struct fd_table *curfds, __wasi_fd_t fd) +wasmtime_ssp_fd_sync(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd) { struct fd_object *fo; __wasi_errno_t error = @@ -1278,15 +1303,15 @@ wasmtime_ssp_fd_sync(struct fd_table *curfds, __wasi_fd_t fd) return error; int ret = fsync(fd_number(fo)); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; } __wasi_errno_t -wasmtime_ssp_fd_write(struct fd_table *curfds, __wasi_fd_t fd, - const __wasi_ciovec_t *iov, size_t iovcnt, +wasmtime_ssp_fd_write(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const __wasi_ciovec_t *iov, size_t iovcnt, size_t *nwritten) { struct fd_object *fo; @@ -1318,7 +1343,7 @@ wasmtime_ssp_fd_write(struct fd_table *curfds, __wasi_fd_t fd, len = writev(fd_number(fo), (const struct iovec *)iov, (int)iovcnt); } #endif /* end of BH_VPRINTF */ - fd_object_release(fo); + fd_object_release(exec_env, fo); if (len < 0) return convert_errno(errno); *nwritten = (size_t)len; @@ -1326,9 +1351,9 @@ wasmtime_ssp_fd_write(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_advise(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_filesize_t offset, __wasi_filesize_t len, - __wasi_advice_t advice) +wasmtime_ssp_fd_advise(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_filesize_t offset, + __wasi_filesize_t len, __wasi_advice_t advice) { #ifdef POSIX_FADV_NORMAL int nadvice; @@ -1362,7 +1387,7 @@ wasmtime_ssp_fd_advise(struct fd_table *curfds, __wasi_fd_t fd, return error; int ret = posix_fadvise(fd_number(fo), (off_t)offset, (off_t)len, nadvice); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret != 0) return convert_errno(ret); return 0; @@ -1392,8 +1417,9 @@ wasmtime_ssp_fd_advise(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_fd_allocate(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_filesize_t offset, __wasi_filesize_t len) +wasmtime_ssp_fd_allocate(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_filesize_t offset, + __wasi_filesize_t len) { struct fd_object *fo; __wasi_errno_t error = @@ -1414,7 +1440,7 @@ wasmtime_ssp_fd_allocate(struct fd_table *curfds, __wasi_fd_t fd, ret = ftruncate(fd_number(fo), newsize); #endif - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret != 0) return convert_errno(ret); return 0; @@ -1569,6 +1595,9 @@ path_get(struct fd_table *curfds, struct path_access *pa, __wasi_fd_t fd, // components. In other words, a pathname component that must be a // directory. First attempt to obtain a directory file descriptor // for it. + // + // Note: we don't bother to use blocking_op_openat here + // because openat with O_DIRECTORY should not block. int newdir = #ifdef O_SEARCH openat(fds[curfd], file, O_SEARCH | O_DIRECTORY | O_NOFOLLOW); @@ -1702,7 +1731,7 @@ fail: close(fds[i]); for (size_t i = 0; i <= curpath; ++i) wasm_runtime_free(paths_start[i]); - fd_object_release(fo); + fd_object_release(NULL, fo); return error; #endif } @@ -1726,11 +1755,12 @@ path_put(struct path_access *pa) UNLOCKS(pa->fd_object->refcount) wasm_runtime_free(pa->path_start); if (fd_number(pa->fd_object) != pa->fd) close(pa->fd); - fd_object_release(pa->fd_object); + fd_object_release(NULL, pa->fd_object); } __wasi_errno_t -wasmtime_ssp_path_create_directory(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_path_create_directory(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, const char *path, size_t pathlen) { struct path_access pa; @@ -1775,11 +1805,11 @@ validate_path(const char *path, struct fd_prestats *pt) } __wasi_errno_t -wasmtime_ssp_path_link(struct fd_table *curfds, struct fd_prestats *prestats, - __wasi_fd_t old_fd, __wasi_lookupflags_t old_flags, - const char *old_path, size_t old_path_len, - __wasi_fd_t new_fd, const char *new_path, - size_t new_path_len) +wasmtime_ssp_path_link(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct fd_prestats *prestats, __wasi_fd_t old_fd, + __wasi_lookupflags_t old_flags, const char *old_path, + size_t old_path_len, __wasi_fd_t new_fd, + const char *new_path, size_t new_path_len) { struct path_access old_pa; __wasi_errno_t error = @@ -1832,9 +1862,9 @@ wasmtime_ssp_path_link(struct fd_table *curfds, struct fd_prestats *prestats, } __wasi_errno_t -wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd, - __wasi_lookupflags_t dirflags, const char *path, - size_t pathlen, __wasi_oflags_t oflags, +wasmtime_ssp_path_open(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t dirfd, __wasi_lookupflags_t dirflags, + const char *path, size_t pathlen, __wasi_oflags_t oflags, __wasi_rights_t fs_rights_base, __wasi_rights_t fs_rights_inheriting, __wasi_fdflags_t fs_flags, __wasi_fd_t *fd) @@ -1908,7 +1938,7 @@ wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd, if (!pa.follow) noflags |= O_NOFOLLOW; - int nfd = openat(pa.fd, pa.path, noflags, 0666); + int nfd = blocking_op_openat(exec_env, pa.fd, pa.path, noflags, 0666); if (nfd < 0) { int openat_errno = errno; // Linux returns ENXIO instead of EOPNOTSUPP when opening a socket. @@ -1965,7 +1995,8 @@ wasmtime_ssp_path_open(struct fd_table *curfds, __wasi_fd_t dirfd, rights_base |= (__wasi_rights_t)RIGHTS_REGULAR_FILE_BASE; } - return fd_table_insert_fd(curfds, nfd, type, rights_base & max_base, + return fd_table_insert_fd(exec_env, curfds, nfd, type, + rights_base & max_base, rights_inheriting & max_inheriting, fd); } @@ -1984,9 +2015,9 @@ fd_readdir_put(void *buf, size_t bufsize, size_t *bufused, const void *elem, } __wasi_errno_t -wasmtime_ssp_fd_readdir(struct fd_table *curfds, __wasi_fd_t fd, void *buf, - size_t nbyte, __wasi_dircookie_t cookie, - size_t *bufused) +wasmtime_ssp_fd_readdir(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, void *buf, size_t nbyte, + __wasi_dircookie_t cookie, size_t *bufused) { struct fd_object *fo; __wasi_errno_t error = @@ -2002,7 +2033,7 @@ wasmtime_ssp_fd_readdir(struct fd_table *curfds, __wasi_fd_t fd, void *buf, dp = fdopendir(fd_number(fo)); if (dp == NULL) { mutex_unlock(&fo->directory.lock); - fd_object_release(fo); + fd_object_release(exec_env, fo); return convert_errno(errno); } fo->directory.handle = dp; @@ -2026,7 +2057,7 @@ wasmtime_ssp_fd_readdir(struct fd_table *curfds, __wasi_fd_t fd, void *buf, struct dirent *de = readdir(dp); if (de == NULL) { mutex_unlock(&fo->directory.lock); - fd_object_release(fo); + fd_object_release(exec_env, fo); return errno == 0 || *bufused > 0 ? 0 : convert_errno(errno); } fo->directory.offset = (__wasi_dircookie_t)telldir(dp); @@ -2075,14 +2106,14 @@ wasmtime_ssp_fd_readdir(struct fd_table *curfds, __wasi_fd_t fd, void *buf, fd_readdir_put(buf, nbyte, bufused, de->d_name, namlen); } mutex_unlock(&fo->directory.lock); - fd_object_release(fo); + fd_object_release(exec_env, fo); return 0; } __wasi_errno_t -wasmtime_ssp_path_readlink(struct fd_table *curfds, __wasi_fd_t fd, - const char *path, size_t pathlen, char *buf, - size_t bufsize, size_t *bufused) +wasmtime_ssp_path_readlink(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const char *path, size_t pathlen, + char *buf, size_t bufsize, size_t *bufused) { struct path_access pa; __wasi_errno_t error = path_get_nofollow( @@ -2103,10 +2134,10 @@ wasmtime_ssp_path_readlink(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_path_rename(struct fd_table *curfds, __wasi_fd_t old_fd, - const char *old_path, size_t old_path_len, - __wasi_fd_t new_fd, const char *new_path, - size_t new_path_len) +wasmtime_ssp_path_rename(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t old_fd, const char *old_path, + size_t old_path_len, __wasi_fd_t new_fd, + const char *new_path, size_t new_path_len) { struct path_access old_pa; __wasi_errno_t error = @@ -2148,8 +2179,8 @@ convert_stat(const struct stat *in, __wasi_filestat_t *out) } __wasi_errno_t -wasmtime_ssp_fd_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_filestat_t *buf) +wasmtime_ssp_fd_filestat_get(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_filestat_t *buf) { struct fd_object *fo; __wasi_errno_t error = @@ -2168,7 +2199,7 @@ wasmtime_ssp_fd_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, } } buf->st_filetype = fo->type; - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; @@ -2218,7 +2249,8 @@ convert_utimens_arguments(__wasi_timestamp_t st_atim, } __wasi_errno_t -wasmtime_ssp_fd_filestat_set_size(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_fd_filestat_set_size(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_filesize_t st_size) { struct fd_object *fo; @@ -2228,14 +2260,15 @@ wasmtime_ssp_fd_filestat_set_size(struct fd_table *curfds, __wasi_fd_t fd, return error; int ret = ftruncate(fd_number(fo), (off_t)st_size); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; } __wasi_errno_t -wasmtime_ssp_fd_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_fd_filestat_set_times(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_timestamp_t st_atim, __wasi_timestamp_t st_mtim, __wasi_fstflags_t fstflags) @@ -2256,14 +2289,15 @@ wasmtime_ssp_fd_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, convert_utimens_arguments(st_atim, st_mtim, fstflags, ts); int ret = futimens(fd_number(fo), ts); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret < 0) return convert_errno(errno); return 0; } __wasi_errno_t -wasmtime_ssp_path_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_path_filestat_get(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, size_t pathlen, __wasi_filestat_t *buf) { @@ -2300,7 +2334,8 @@ wasmtime_ssp_path_filestat_get(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_path_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_path_filestat_set_times(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, size_t pathlen, __wasi_timestamp_t st_atim, @@ -2338,10 +2373,10 @@ wasmtime_ssp_path_filestat_set_times(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_path_symlink(struct fd_table *curfds, struct fd_prestats *prestats, - const char *old_path, size_t old_path_len, - __wasi_fd_t fd, const char *new_path, - size_t new_path_len) +wasmtime_ssp_path_symlink(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct fd_prestats *prestats, const char *old_path, + size_t old_path_len, __wasi_fd_t fd, + const char *new_path, size_t new_path_len) { char *target = str_nullterminate(old_path, old_path_len); if (target == NULL) @@ -2373,8 +2408,8 @@ wasmtime_ssp_path_symlink(struct fd_table *curfds, struct fd_prestats *prestats, } __wasi_errno_t -wasmtime_ssp_path_unlink_file(struct fd_table *curfds, __wasi_fd_t fd, - const char *path, size_t pathlen) +wasmtime_ssp_path_unlink_file(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, const char *path, size_t pathlen) { struct path_access pa; __wasi_errno_t error = path_get_nofollow( @@ -2407,7 +2442,8 @@ wasmtime_ssp_path_unlink_file(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_path_remove_directory(struct fd_table *curfds, __wasi_fd_t fd, +wasmtime_ssp_path_remove_directory(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, const char *path, size_t pathlen) { struct path_access pa; @@ -2433,7 +2469,7 @@ wasmtime_ssp_path_remove_directory(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_poll_oneoff(struct fd_table *curfds, +wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds, const __wasi_subscription_t *in, __wasi_event_t *out, size_t nsubscriptions, size_t *nevents) NO_LOCK_ANALYSIS @@ -2681,7 +2717,7 @@ wasmtime_ssp_poll_oneoff(struct fd_table *curfds, for (size_t i = 0; i < nsubscriptions; ++i) if (fos[i] != NULL) - fd_object_release(fos[i]); + fd_object_release(exec_env, fos[i]); wasm_runtime_free(fos); wasm_runtime_free(pfds); return error; @@ -2695,8 +2731,9 @@ wasmtime_ssp_random_get(void *buf, size_t nbyte) } __wasi_errno_t -wasi_ssp_sock_accept(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_fdflags_t flags, __wasi_fd_t *fd_new) +wasi_ssp_sock_accept(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_fdflags_t flags, + __wasi_fd_t *fd_new) { __wasi_filetype_t wasi_type; __wasi_rights_t max_base, max_inheriting; @@ -2709,8 +2746,9 @@ wasi_ssp_sock_accept(struct fd_table *curfds, __wasi_fd_t fd, goto fail; } - ret = os_socket_accept(fd_number(fo), &new_sock, NULL, NULL); - fd_object_release(fo); + ret = blocking_op_socket_accept(exec_env, fd_number(fo), &new_sock, NULL, + NULL); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { error = convert_errno(errno); goto fail; @@ -2722,7 +2760,7 @@ wasi_ssp_sock_accept(struct fd_table *curfds, __wasi_fd_t fd, goto fail; } - error = fd_table_insert_fd(curfds, new_sock, wasi_type, max_base, + error = fd_table_insert_fd(exec_env, curfds, new_sock, wasi_type, max_base, max_inheriting, fd_new); if (error != __WASI_ESUCCESS) { /* released in fd_table_insert_fd() */ @@ -2740,8 +2778,8 @@ fail: } __wasi_errno_t -wasi_ssp_sock_addr_local(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_addr_t *addr) +wasi_ssp_sock_addr_local(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_addr_t *addr) { struct fd_object *fo; bh_sockaddr_t bh_addr; @@ -2753,7 +2791,7 @@ wasi_ssp_sock_addr_local(struct fd_table *curfds, __wasi_fd_t fd, return error; ret = os_socket_addr_local(fd_number(fo), &bh_addr); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret != BHT_OK) { return convert_errno(errno); } @@ -2764,8 +2802,8 @@ wasi_ssp_sock_addr_local(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_addr_remote(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_addr_t *addr) +wasi_ssp_sock_addr_remote(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_addr_t *addr) { struct fd_object *fo; bh_sockaddr_t bh_addr; @@ -2777,7 +2815,7 @@ wasi_ssp_sock_addr_remote(struct fd_table *curfds, __wasi_fd_t fd, return error; ret = os_socket_addr_remote(fd_number(fo), &bh_addr); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (ret != BHT_OK) { return convert_errno(errno); } @@ -2817,8 +2855,9 @@ wasi_addr_to_string(const __wasi_addr_t *addr, char *buf, size_t buflen) } __wasi_errno_t -wasi_ssp_sock_bind(struct fd_table *curfds, struct addr_pool *addr_pool, - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_bind(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct addr_pool *addr_pool, __wasi_fd_t fd, + __wasi_addr_t *addr) { char buf[48] = { 0 }; struct fd_object *fo; @@ -2839,7 +2878,7 @@ wasi_ssp_sock_bind(struct fd_table *curfds, struct addr_pool *addr_pool, return error; ret = os_socket_bind(fd_number(fo), buf, &port); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -2848,9 +2887,9 @@ wasi_ssp_sock_bind(struct fd_table *curfds, struct addr_pool *addr_pool, } __wasi_errno_t -wasi_ssp_sock_addr_resolve(struct fd_table *curfds, char **ns_lookup_list, - const char *host, const char *service, - __wasi_addr_info_hints_t *hints, +wasi_ssp_sock_addr_resolve(wasm_exec_env_t exec_env, struct fd_table *curfds, + char **ns_lookup_list, const char *host, + const char *service, __wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info, __wasi_size_t addr_info_size, __wasi_size_t *max_info_size) @@ -2871,8 +2910,8 @@ wasi_ssp_sock_addr_resolve(struct fd_table *curfds, char **ns_lookup_list, return __WASI_EACCES; } - int ret = os_socket_addr_resolve( - host, service, + int ret = blocking_op_socket_addr_resolve( + exec_env, host, service, hints->hints_enabled && hints->type != SOCKET_ANY ? &hints_is_tcp : NULL, hints->hints_enabled && hints->family != INET_UNSPEC ? &hints_is_ipv4 @@ -2900,8 +2939,9 @@ wasi_ssp_sock_addr_resolve(struct fd_table *curfds, char **ns_lookup_list, } __wasi_errno_t -wasi_ssp_sock_connect(struct fd_table *curfds, struct addr_pool *addr_pool, - __wasi_fd_t fd, __wasi_addr_t *addr) +wasi_ssp_sock_connect(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct addr_pool *addr_pool, __wasi_fd_t fd, + __wasi_addr_t *addr) { char buf[48] = { 0 }; struct fd_object *fo; @@ -2920,10 +2960,10 @@ wasi_ssp_sock_connect(struct fd_table *curfds, struct addr_pool *addr_pool, if (error != __WASI_ESUCCESS) return error; - ret = os_socket_connect(fd_number(fo), buf, - addr->kind == IPv4 ? addr->addr.ip4.port - : addr->addr.ip6.port); - fd_object_release(fo); + ret = blocking_op_socket_connect(exec_env, fd_number(fo), buf, + addr->kind == IPv4 ? addr->addr.ip4.port + : addr->addr.ip6.port); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -2932,7 +2972,8 @@ wasi_ssp_sock_connect(struct fd_table *curfds, struct addr_pool *addr_pool, } __wasi_errno_t -wasi_ssp_sock_get_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, +wasi_ssp_sock_get_recv_buf_size(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t *size) { struct fd_object *fo; @@ -2945,7 +2986,7 @@ wasi_ssp_sock_get_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, socklen_t optlen = sizeof(optval); ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_RCVBUF, &optval, &optlen); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -2956,8 +2997,8 @@ wasi_ssp_sock_get_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_get_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, - uint8_t *reuse) +wasi_ssp_sock_get_reuse_addr(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, uint8_t *reuse) { struct fd_object *fo; @@ -2970,7 +3011,7 @@ wasi_ssp_sock_get_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, socklen_t optlen = sizeof(optval); ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEADDR, &optval, &optlen); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -2981,8 +3022,8 @@ wasi_ssp_sock_get_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_get_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, - uint8_t *reuse) +wasi_ssp_sock_get_reuse_port(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, uint8_t *reuse) { struct fd_object *fo; int ret; @@ -3001,7 +3042,7 @@ wasi_ssp_sock_get_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, optval = 0; #endif /* defined(SO_REUSEPORT) */ - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3012,7 +3053,8 @@ wasi_ssp_sock_get_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_get_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, +wasi_ssp_sock_get_send_buf_size(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t *size) { struct fd_object *fo; @@ -3025,7 +3067,7 @@ wasi_ssp_sock_get_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, socklen_t optlen = sizeof(optval); ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_SNDBUF, &optval, &optlen); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3036,8 +3078,8 @@ wasi_ssp_sock_get_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_listen(struct fd_table *curfds, __wasi_fd_t fd, - __wasi_size_t backlog) +wasi_ssp_sock_listen(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, __wasi_size_t backlog) { struct fd_object *fo; int ret; @@ -3047,7 +3089,7 @@ wasi_ssp_sock_listen(struct fd_table *curfds, __wasi_fd_t fd, return error; ret = os_socket_listen(fd_number(fo), backlog); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3056,9 +3098,9 @@ wasi_ssp_sock_listen(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_open(struct fd_table *curfds, __wasi_fd_t poolfd, - __wasi_address_family_t af, __wasi_sock_type_t socktype, - __wasi_fd_t *sockfd) +wasi_ssp_sock_open(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t poolfd, __wasi_address_family_t af, + __wasi_sock_type_t socktype, __wasi_fd_t *sockfd) { bh_socket_t sock; bool is_tcp = SOCKET_DGRAM == socktype ? false : true; @@ -3090,7 +3132,7 @@ wasi_ssp_sock_open(struct fd_table *curfds, __wasi_fd_t poolfd, } // TODO: base rights and inheriting rights ? - error = fd_table_insert_fd(curfds, sock, wasi_type, max_base, + error = fd_table_insert_fd(exec_env, curfds, sock, wasi_type, max_base, max_inheriting, sockfd); if (error != __WASI_ESUCCESS) { return error; @@ -3100,7 +3142,8 @@ wasi_ssp_sock_open(struct fd_table *curfds, __wasi_fd_t poolfd, } __wasi_errno_t -wasi_ssp_sock_set_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, +wasi_ssp_sock_set_recv_buf_size(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t size) { struct fd_object *fo; @@ -3113,7 +3156,7 @@ wasi_ssp_sock_set_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval)); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3122,8 +3165,8 @@ wasi_ssp_sock_set_recv_buf_size(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_set_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, - uint8_t reuse) +wasi_ssp_sock_set_reuse_addr(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, uint8_t reuse) { struct fd_object *fo; int ret; @@ -3135,7 +3178,7 @@ wasi_ssp_sock_set_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3144,8 +3187,8 @@ wasi_ssp_sock_set_reuse_addr(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_set_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, - uint8_t reuse) +wasi_ssp_sock_set_reuse_port(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t fd, uint8_t reuse) { struct fd_object *fo; int ret; @@ -3163,7 +3206,7 @@ wasi_ssp_sock_set_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, ret = BHT_ERROR; #endif /* defined(SO_REUSEPORT) */ - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3172,7 +3215,8 @@ wasi_ssp_sock_set_reuse_port(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasi_ssp_sock_set_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, +wasi_ssp_sock_set_send_buf_size(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t fd, __wasi_size_t size) { struct fd_object *fo; @@ -3186,7 +3230,7 @@ wasi_ssp_sock_set_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) { return convert_errno(errno); } @@ -3195,18 +3239,19 @@ wasi_ssp_sock_set_send_buf_size(struct fd_table *curfds, __wasi_fd_t fd, } __wasi_errno_t -wasmtime_ssp_sock_recv(struct fd_table *curfds, __wasi_fd_t sock, void *buf, - size_t buf_len, size_t *recv_len) +wasmtime_ssp_sock_recv(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock, void *buf, size_t buf_len, + size_t *recv_len) { __wasi_addr_t src_addr; - return wasmtime_ssp_sock_recv_from(curfds, sock, buf, buf_len, 0, &src_addr, - recv_len); + return wasmtime_ssp_sock_recv_from(exec_env, curfds, sock, buf, buf_len, 0, + &src_addr, recv_len); } __wasi_errno_t -wasmtime_ssp_sock_recv_from(struct fd_table *curfds, __wasi_fd_t sock, - void *buf, size_t buf_len, +wasmtime_ssp_sock_recv_from(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock, void *buf, size_t buf_len, __wasi_riflags_t ri_flags, __wasi_addr_t *src_addr, size_t *recv_len) { @@ -3220,8 +3265,9 @@ wasmtime_ssp_sock_recv_from(struct fd_table *curfds, __wasi_fd_t sock, return error; } - ret = os_socket_recv_from(fd_number(fo), buf, buf_len, 0, &sockaddr); - fd_object_release(fo); + ret = blocking_op_socket_recv_from(exec_env, fd_number(fo), buf, buf_len, 0, + &sockaddr); + fd_object_release(exec_env, fo); if (-1 == ret) { return convert_errno(errno); } @@ -3233,8 +3279,9 @@ wasmtime_ssp_sock_recv_from(struct fd_table *curfds, __wasi_fd_t sock, } __wasi_errno_t -wasmtime_ssp_sock_send(struct fd_table *curfds, __wasi_fd_t sock, - const void *buf, size_t buf_len, size_t *sent_len) +wasmtime_ssp_sock_send(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock, const void *buf, size_t buf_len, + size_t *sent_len) { struct fd_object *fo; __wasi_errno_t error; @@ -3246,7 +3293,7 @@ wasmtime_ssp_sock_send(struct fd_table *curfds, __wasi_fd_t sock, } ret = os_socket_send(fd_number(fo), buf, buf_len); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (-1 == ret) { return convert_errno(errno); } @@ -3256,8 +3303,9 @@ wasmtime_ssp_sock_send(struct fd_table *curfds, __wasi_fd_t sock, } __wasi_errno_t -wasmtime_ssp_sock_send_to(struct fd_table *curfds, struct addr_pool *addr_pool, - __wasi_fd_t sock, const void *buf, size_t buf_len, +wasmtime_ssp_sock_send_to(wasm_exec_env_t exec_env, struct fd_table *curfds, + struct addr_pool *addr_pool, __wasi_fd_t sock, + const void *buf, size_t buf_len, __wasi_siflags_t si_flags, const __wasi_addr_t *dest_addr, size_t *sent_len) { @@ -3282,8 +3330,9 @@ wasmtime_ssp_sock_send_to(struct fd_table *curfds, struct addr_pool *addr_pool, wasi_addr_to_bh_sockaddr(dest_addr, &sockaddr); - ret = os_socket_send_to(fd_number(fo), buf, buf_len, 0, &sockaddr); - fd_object_release(fo); + ret = blocking_op_socket_send_to(exec_env, fd_number(fo), buf, buf_len, 0, + &sockaddr); + fd_object_release(exec_env, fo); if (-1 == ret) { return convert_errno(errno); } @@ -3293,7 +3342,8 @@ wasmtime_ssp_sock_send_to(struct fd_table *curfds, struct addr_pool *addr_pool, } __wasi_errno_t -wasmtime_ssp_sock_shutdown(struct fd_table *curfds, __wasi_fd_t sock) +wasmtime_ssp_sock_shutdown(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock) { struct fd_object *fo; __wasi_errno_t error; @@ -3304,7 +3354,7 @@ wasmtime_ssp_sock_shutdown(struct fd_table *curfds, __wasi_fd_t sock) return error; ret = os_socket_shutdown(fd_number(fo)); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); @@ -3396,7 +3446,7 @@ fd_table_destroy(struct fd_table *ft) if (ft->entries) { for (uint32 i = 0; i < ft->size; i++) { if (ft->entries[i].object != NULL) { - fd_object_release(ft->entries[i].object); + fd_object_release(NULL, ft->entries[i].object); } } rwlock_destroy(&ft->lock); @@ -3591,6 +3641,7 @@ addr_pool_destroy(struct addr_pool *addr_pool) // implementation #define WASMTIME_SSP_PASSTHROUGH_SOCKET_OPTION(FUNC_NAME, OPTION_TYPE) \ __wasi_errno_t wasmtime_ssp_sock_##FUNC_NAME( \ + wasm_exec_env_t exec_env, \ WASMTIME_SSP_PASSTHROUGH_FD_TABLE __wasi_fd_t sock, \ OPTION_TYPE option) \ { \ @@ -3601,7 +3652,7 @@ addr_pool_destroy(struct addr_pool *addr_pool) if (error != 0) \ return error; \ ret = os_socket_##FUNC_NAME(fd_number(fo), option); \ - fd_object_release(fo); \ + fd_object_release(exec_env, fo); \ if (BHT_OK != ret) \ return convert_errno(errno); \ return __WASI_ESUCCESS; \ @@ -3644,8 +3695,8 @@ WASMTIME_SSP_PASSTHROUGH_SOCKET_OPTION(get_ipv6_only, bool *) #undef WASMTIME_SSP_PASSTHROUGH_SOCKET_OPTION __wasi_errno_t -wasmtime_ssp_sock_set_linger(struct fd_table *curfds, __wasi_fd_t sock, - bool is_enabled, int linger_s) +wasmtime_ssp_sock_set_linger(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock, bool is_enabled, int linger_s) { struct fd_object *fo; __wasi_errno_t error; @@ -3655,15 +3706,15 @@ wasmtime_ssp_sock_set_linger(struct fd_table *curfds, __wasi_fd_t sock, return error; ret = os_socket_set_linger(fd_number(fo), is_enabled, linger_s); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); return __WASI_ESUCCESS; } __wasi_errno_t -wasmtime_ssp_sock_get_linger(struct fd_table *curfds, __wasi_fd_t sock, - bool *is_enabled, int *linger_s) +wasmtime_ssp_sock_get_linger(wasm_exec_env_t exec_env, struct fd_table *curfds, + __wasi_fd_t sock, bool *is_enabled, int *linger_s) { struct fd_object *fo; __wasi_errno_t error; @@ -3673,7 +3724,7 @@ wasmtime_ssp_sock_get_linger(struct fd_table *curfds, __wasi_fd_t sock, return error; ret = os_socket_get_linger(fd_number(fo), is_enabled, linger_s); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); @@ -3681,7 +3732,8 @@ wasmtime_ssp_sock_get_linger(struct fd_table *curfds, __wasi_fd_t sock, } __wasi_errno_t -wasmtime_ssp_sock_set_ip_add_membership(struct fd_table *curfds, +wasmtime_ssp_sock_set_ip_add_membership(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface) @@ -3699,14 +3751,15 @@ wasmtime_ssp_sock_set_ip_add_membership(struct fd_table *curfds, is_ipv6 = imr_multiaddr->kind == IPv6; ret = os_socket_set_ip_add_membership(fd_number(fo), &addr_info, imr_interface, is_ipv6); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); return __WASI_ESUCCESS; } __wasi_errno_t -wasmtime_ssp_sock_set_ip_drop_membership(struct fd_table *curfds, +wasmtime_ssp_sock_set_ip_drop_membership(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t sock, __wasi_addr_ip_t *imr_multiaddr, uint32_t imr_interface) @@ -3724,14 +3777,15 @@ wasmtime_ssp_sock_set_ip_drop_membership(struct fd_table *curfds, is_ipv6 = imr_multiaddr->kind == IPv6; ret = os_socket_set_ip_drop_membership(fd_number(fo), &addr_info, imr_interface, is_ipv6); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); return __WASI_ESUCCESS; } __wasi_errno_t -wasmtime_ssp_sock_set_ip_multicast_loop(struct fd_table *curfds, +wasmtime_ssp_sock_set_ip_multicast_loop(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t sock, bool ipv6, bool is_enabled) { @@ -3743,14 +3797,15 @@ wasmtime_ssp_sock_set_ip_multicast_loop(struct fd_table *curfds, return error; ret = os_socket_set_ip_multicast_loop(fd_number(fo), ipv6, is_enabled); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); return __WASI_ESUCCESS; } __wasi_errno_t -wasmtime_ssp_sock_get_ip_multicast_loop(struct fd_table *curfds, +wasmtime_ssp_sock_get_ip_multicast_loop(wasm_exec_env_t exec_env, + struct fd_table *curfds, __wasi_fd_t sock, bool ipv6, bool *is_enabled) { @@ -3762,7 +3817,7 @@ wasmtime_ssp_sock_get_ip_multicast_loop(struct fd_table *curfds, return error; ret = os_socket_get_ip_multicast_loop(fd_number(fo), ipv6, is_enabled); - fd_object_release(fo); + fd_object_release(exec_env, fo); if (BHT_OK != ret) return convert_errno(errno); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 06be3bc89..49545de72 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -1059,6 +1059,10 @@ set_thread_cancel_flags(WASMExecEnv *exec_env) WASM_SUSPEND_FLAG_TERMINATE); os_mutex_unlock(&exec_env->wait_lock); + +#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP + wasm_runtime_interrupt_blocking_op(exec_env); +#endif } static void diff --git a/core/shared/platform/common/posix/posix_blocking_op.c b/core/shared/platform/common/posix/posix_blocking_op.c new file mode 100644 index 000000000..560828a06 --- /dev/null +++ b/core/shared/platform/common/posix/posix_blocking_op.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Midokura Japan KK. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_extension.h" + +#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP + +static bool g_blocking_op_inited = false; +static int g_blocking_op_signo = SIGUSR1; +static sigset_t g_blocking_op_sigmask; + +static void +blocking_op_sighandler(int signo) +{ + /* nothing */ +} + +void +os_set_signal_number_for_blocking_op(int signo) +{ + g_blocking_op_signo = signo; +} + +int +os_blocking_op_init() +{ + if (g_blocking_op_inited) { + return BHT_OK; + } + + sigemptyset(&g_blocking_op_sigmask); + sigaddset(&g_blocking_op_sigmask, g_blocking_op_signo); + + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = blocking_op_sighandler; + if (sigaction(g_blocking_op_signo, &sa, NULL)) { + return BHT_ERROR; + } + g_blocking_op_inited = true; + return BHT_OK; +} + +void +os_begin_blocking_op() +{ + pthread_sigmask(SIG_UNBLOCK, &g_blocking_op_sigmask, NULL); +} + +void +os_end_blocking_op() +{ + pthread_sigmask(SIG_BLOCK, &g_blocking_op_sigmask, NULL); +} + +int +os_wakeup_blocking_op(korp_tid tid) +{ + int ret = pthread_kill(tid, g_blocking_op_signo); + if (ret != 0) { + return BHT_ERROR; + } + return BHT_OK; +} + +#endif /* OS_ENABLE_WAKEUP_BLOCKING_OP */ diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index b1460f6b5..a0b184405 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -39,6 +39,9 @@ os_thread_wrapper(void *arg) #ifdef OS_ENABLE_HW_BOUND_CHECK if (os_thread_signal_init(handler) != 0) return NULL; +#endif +#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP + os_end_blocking_op(); #endif start_func(thread_arg); #ifdef OS_ENABLE_HW_BOUND_CHECK diff --git a/core/shared/platform/darwin/platform_internal.h b/core/shared/platform/darwin/platform_internal.h index 3fd1c258e..5cd037a20 100644 --- a/core/shared/platform/darwin/platform_internal.h +++ b/core/shared/platform/darwin/platform_internal.h @@ -102,6 +102,12 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ +#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#define OS_ENABLE_WAKEUP_BLOCKING_OP +#endif +void +os_set_signal_number_for_blocking_op(int signo); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/freebsd/platform_internal.h b/core/shared/platform/freebsd/platform_internal.h index 7b4789c99..ed1d4efa4 100644 --- a/core/shared/platform/freebsd/platform_internal.h +++ b/core/shared/platform/freebsd/platform_internal.h @@ -101,6 +101,12 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ +#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#define OS_ENABLE_WAKEUP_BLOCKING_OP +#endif +void +os_set_signal_number_for_blocking_op(int signo); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 5b7b556e0..06bd9ee89 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -323,6 +323,34 @@ os_sem_getvalue(korp_sem *sem, int *sval); int os_sem_unlink(const char *name); +/** + * Initialize process-global state for os_wakeup_blocking_op. + */ +int +os_blocking_op_init(); + +/** + * Start accepting os_wakeup_blocking_op requests for the calling thread. + */ +void +os_begin_blocking_op(); + +/** + * Stop accepting os_wakeup_blocking_op requests for the calling thread. + */ +void +os_end_blocking_op(); + +/** + * Wake up the specified thread. + * + * For example, on posix-like platforms, this can be implemented by + * sending a signal (w/o SA_RESTART) which interrupts a blocking + * system call. + */ +int +os_wakeup_blocking_op(korp_tid tid); + /**************************************************** * Section 2 * * Socket support * diff --git a/core/shared/platform/linux/platform_internal.h b/core/shared/platform/linux/platform_internal.h index 8439f8723..222a6fc57 100644 --- a/core/shared/platform/linux/platform_internal.h +++ b/core/shared/platform/linux/platform_internal.h @@ -115,6 +115,12 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ +#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#define OS_ENABLE_WAKEUP_BLOCKING_OP +#endif +void +os_set_signal_number_for_blocking_op(int signo); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/nuttx/platform_internal.h b/core/shared/platform/nuttx/platform_internal.h index b5bbdacd0..c53857e0f 100644 --- a/core/shared/platform/nuttx/platform_internal.h +++ b/core/shared/platform/nuttx/platform_internal.h @@ -123,6 +123,12 @@ utimensat(int fd, const char *path, const struct timespec ts[2], int flag); DIR * fdopendir(int fd); +#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#define OS_ENABLE_WAKEUP_BLOCKING_OP +#endif +void +os_set_signal_number_for_blocking_op(int signo); + #ifdef __cplusplus } #endif diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 81b4f6211..9938eadcb 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -109,6 +109,10 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM - **WAMR_DISABLE_STACK_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform, same as `WAMR_DISABLE_HW_BOUND_CHECK`. > Note: When boundary check with hardware trap is disabled, or `WAMR_DISABLE_HW_BOUND_CHECK` is set to 1, the native stack boundary check with hardware trap will be disabled too, no matter what value is set to `WAMR_DISABLE_STACK_HW_BOUND_CHECK`. And when boundary check with hardware trap is enabled, the status of this feature is set according to the value of `WAMR_DISABLE_STACK_HW_BOUND_CHECK`. +#### **Disable async wakeup of blocking operation** +- **WAMR_DISABLE_WAKEUP_BLOCKING_OP**=1/0, default to enable if supported by the platform +> Note: The feature helps async termination of blocking threads. If you disable it, the runtime can wait for termination of blocking threads possibly forever. + #### **Enable tail call feature** - **WAMR_BUILD_TAIL_CALL**=1/0, default to disable if not set diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index e5af62cc8..04a6db91f 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -246,6 +246,7 @@ ifeq ($(CONFIG_INTERPRETERS_WAMR_LIBC_WASI),y) CFLAGS += -DWASM_ENABLE_LIBC_WASI=1 CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/src CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/include +CSRCS += blocking_op.c CSRCS += posix_socket.c CSRCS += libc_wasi_wrapper.c VPATH += $(IWASM_ROOT)/libraries/libc-wasi @@ -309,6 +310,9 @@ CFLAGS += -DWASM_DISABLE_HW_BOUND_CHECK=0 CFLAGS += -DWASM_DISABLE_STACK_HW_BOUND_CHECK=0 endif +# REVISIT: is this worth to have a Kconfig? +CFLAGS += -DWASM_DISABLE_WAKEUP_BLOCKING_OP=0 + ifeq ($(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS),y) CFLAGS += -DWASM_ENABLE_CUSTOM_NAME_SECTION=1 else @@ -354,8 +358,10 @@ CFLAGS += -I$(IWASM_ROOT)/interpreter endif CSRCS += nuttx_platform.c \ + posix_blocking_op.c \ posix_thread.c \ posix_time.c \ + posix_sleep.c \ mem_alloc.c \ ems_kfc.c \ ems_alloc.c \ @@ -370,6 +376,7 @@ CSRCS += nuttx_platform.c \ bh_read_file.c \ runtime_timer.c \ wasm_application.c \ + wasm_blocking_op.c \ wasm_runtime_common.c \ wasm_native.c \ wasm_exec_env.c \ From 6fca48d8e6b85c69d18a795daef64bae13e9cb62 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 21 Sep 2023 12:56:21 +0900 Subject: [PATCH 24/58] Fix inverted WASM_DISABLE_WAKEUP_BLOCKING_OP checks (#2571) --- core/shared/platform/darwin/platform_internal.h | 2 +- core/shared/platform/freebsd/platform_internal.h | 2 +- core/shared/platform/linux/platform_internal.h | 2 +- core/shared/platform/nuttx/platform_internal.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/shared/platform/darwin/platform_internal.h b/core/shared/platform/darwin/platform_internal.h index 5cd037a20..d72d48b53 100644 --- a/core/shared/platform/darwin/platform_internal.h +++ b/core/shared/platform/darwin/platform_internal.h @@ -102,7 +102,7 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ -#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0 #define OS_ENABLE_WAKEUP_BLOCKING_OP #endif void diff --git a/core/shared/platform/freebsd/platform_internal.h b/core/shared/platform/freebsd/platform_internal.h index ed1d4efa4..50cabd344 100644 --- a/core/shared/platform/freebsd/platform_internal.h +++ b/core/shared/platform/freebsd/platform_internal.h @@ -101,7 +101,7 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ -#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0 #define OS_ENABLE_WAKEUP_BLOCKING_OP #endif void diff --git a/core/shared/platform/linux/platform_internal.h b/core/shared/platform/linux/platform_internal.h index 222a6fc57..337cdd9cc 100644 --- a/core/shared/platform/linux/platform_internal.h +++ b/core/shared/platform/linux/platform_internal.h @@ -115,7 +115,7 @@ os_sigreturn(); #endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ #endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ -#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0 #define OS_ENABLE_WAKEUP_BLOCKING_OP #endif void diff --git a/core/shared/platform/nuttx/platform_internal.h b/core/shared/platform/nuttx/platform_internal.h index c53857e0f..97ab5f697 100644 --- a/core/shared/platform/nuttx/platform_internal.h +++ b/core/shared/platform/nuttx/platform_internal.h @@ -123,7 +123,7 @@ utimensat(int fd, const char *path, const struct timespec ts[2], int flag); DIR * fdopendir(int fd); -#if WASM_DISABLE_WAKEUP_BLOCKING_OP != 0 +#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0 #define OS_ENABLE_WAKEUP_BLOCKING_OP #endif void From c7a7db21b787eda010bb7c52ce33867a8c26f928 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 21 Sep 2023 14:32:08 +0900 Subject: [PATCH 25/58] export_native_api.md: Add a note about thread termination (#2572) --- doc/export_native_api.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/export_native_api.md b/doc/export_native_api.md index b87d92552..e293e5c0d 100644 --- a/doc/export_native_api.md +++ b/doc/export_native_api.md @@ -261,4 +261,32 @@ wasm_response_send(wasm_exec_env_t exec_env, char *buffer, int size) ``` +## Native API implementation notes +### Async thread termination + +When threading support is enabled, a thread can be requested to terminate +itself either explicitly by the `wasm_runtime_terminate` API or implicitly +by cluster-wide activities like WASI `proc_exit`. +If a call to your native function can take long or even forever, +you should make it to respond to termination requests in a timely manner. +There are a few implementation approaches for that: + +* Design your API so that it always returns in a timely manner. + This is the most simple approach when possible. + +* Make your native function check the cluster state by calling + `wasm_cluster_is_thread_terminated` from time to time. + If `wasm_cluster_is_thread_terminated` returns true, make your + native function return. + Note: as of writing this, `wasm_cluster_is_thread_terminated` is not + exported as a runtime API. + +* If your native function is a simple wrapper of blocking system call, + you can probably use the `wasm_runtime_begin_blocking_op` and + `wasm_runtime_end_blocking_op` runtime API. + See the comment in `wamr_export.h` for details. + +* If your native function is very complex, it might be simpler to put the + guts of it into a separate worker process so that it can be cleaned up + by simply killing it. From 47daaeecc7fcd22f4f26b5e229f6ec3dc2602b65 Mon Sep 17 00:00:00 2001 From: ZHU Hao Date: Thu, 21 Sep 2023 13:33:03 +0800 Subject: [PATCH 26/58] Fix compiling error for RT-Thread (#2569) struct dfs_fd has been deprecated --- product-mini/platforms/rt-thread/iwasm.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/product-mini/platforms/rt-thread/iwasm.c b/product-mini/platforms/rt-thread/iwasm.c index 8ae4da761..9a21301d8 100644 --- a/product-mini/platforms/rt-thread/iwasm.c +++ b/product-mini/platforms/rt-thread/iwasm.c @@ -10,7 +10,6 @@ #include #include #include -#include #ifdef WAMR_ENABLE_RTT_EXPORT @@ -183,8 +182,6 @@ rt_uint8_t * my_read_file_to_buffer(char *filename, rt_uint32_t *size) { struct stat f_stat; - dfs_file_stat(filename, &f_stat); - struct dfs_fd fd; rt_uint8_t *buff = rt_malloc(f_stat.st_size); *size = 0; @@ -193,16 +190,16 @@ my_read_file_to_buffer(char *filename, rt_uint32_t *size) return RT_NULL; } - int ret = dfs_file_open(&fd, filename, O_RDONLY); - if (ret) { + int fd = open(filename, O_RDONLY); + if (fd < 0) { rt_free(buff); - rt_set_errno(ret); + rt_set_errno(fd); return RT_NULL; } - *size = dfs_file_read(&fd, buff, f_stat.st_size); + *size = read(fd, buff, f_stat.st_size); - dfs_file_close(&fd); + close(fd); if (*size != f_stat.st_size) { rt_free(buff); From cf97ee081f0efce4ed34a7858eb763beb5998676 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 21 Sep 2023 19:39:12 +0900 Subject: [PATCH 27/58] test_wamr.sh: Print a bit more meaningful message (#2574) --- tests/wamr-test-suites/test_wamr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index f33655207..06231f1e1 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -508,7 +508,7 @@ function wasi_certification_test() cd ${WORK_DIR} if [ ! -d "wasi-testsuite" ]; then - echo "wasi not exist, clone it from github" + echo "wasi-testsuite not exist, clone it from github" git clone -b prod/testsuite-all \ --single-branch https://github.com/WebAssembly/wasi-testsuite.git fi From 0677288f2216dfef86fed6d85bbd110ab668bd27 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 22 Sep 2023 09:57:48 +0900 Subject: [PATCH 28/58] run_wasi_tests.sh: Provide stdin by ourselves (#2576) This improves test consistency between typical local environments and github runners. This is necessary for some of latest wasi-threads tests. cf. https://github.com/yamt/toywasm/commit/570e6706312cbdccb9d5268347186b441a24444b --- .../wamr-test-suites/wasi-test-script/pipe.py | 19 +++++++++++++++++++ .../wasi-test-script/run_wasi_tests.sh | 7 +++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/wamr-test-suites/wasi-test-script/pipe.py diff --git a/tests/wamr-test-suites/wasi-test-script/pipe.py b/tests/wamr-test-suites/wasi-test-script/pipe.py new file mode 100644 index 000000000..e37408717 --- /dev/null +++ b/tests/wamr-test-suites/wasi-test-script/pipe.py @@ -0,0 +1,19 @@ +#! /usr/bin/env python3 + +# Copyright (C) 2023 YAMAMOTO Takashi +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This is a copy of https://github.com/yamt/toywasm/blob/master/test/pipe.py + +# keep stdout open until the peer closes it + +import sys +import select + +p = select.poll() +p.register(sys.stdout, select.POLLHUP) +# http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=57369 +while True: + l = p.poll(1) + if l: + break diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 37607859b..03ad9e27a 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -5,6 +5,8 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # +THIS_DIR=$(cd $(dirname $0) && pwd -P) + readonly MODE=$1 readonly TARGET=$2 @@ -63,7 +65,8 @@ if [[ $MODE != "aot" ]];then python3 -m venv wasi-env && source wasi-env/bin/activate python3 -m pip install -r test-runner/requirements.txt - TEST_RUNTIME_EXE="${IWASM_CMD}" python3 test-runner/wasi_test_runner.py \ + export TEST_RUNTIME_EXE="${IWASM_CMD}" + python3 ${THIS_DIR}/pipe.py | python3 test-runner/wasi_test_runner.py \ -r adapters/wasm-micro-runtime.py \ -t \ ${C_TESTS} \ @@ -100,4 +103,4 @@ else done fi -exit ${exit_code} \ No newline at end of file +exit ${exit_code} From 06527f724e8b0bc79cdf8e73f78749e4caa9490f Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Fri, 22 Sep 2023 02:11:25 +0100 Subject: [PATCH 29/58] Remove provision of unnecessary fd rights (#2579) The WASI docs allow for fewer rights to be applied to an fd than requested but not more. This behavior is also asserted in the rust WASI tests, so it's necessary for those to pass as well. --- .../sandboxed-system-primitives/src/posix.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index c096511c9..bb6d67a62 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -1981,20 +1981,6 @@ wasmtime_ssp_path_open(wasm_exec_env_t exec_env, struct fd_table *curfds, return error; } - { - struct stat sb; - - if (fstat(nfd, &sb) < 0) { - close(nfd); - return convert_errno(errno); - } - - if (S_ISDIR(sb.st_mode)) - rights_base |= (__wasi_rights_t)RIGHTS_DIRECTORY_BASE; - else if (S_ISREG(sb.st_mode)) - rights_base |= (__wasi_rights_t)RIGHTS_REGULAR_FILE_BASE; - } - return fd_table_insert_fd(exec_env, curfds, nfd, type, rights_base & max_base, rights_inheriting & max_inheriting, fd); From 71e07a7fa42e3a3dd2ba7c1b869fe9d7a0af5a7c Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Sat, 23 Sep 2023 09:06:35 +0800 Subject: [PATCH 30/58] Fix potential unaligned store issue when extra return value is v128 (#2583) Unaligned store v128 value to the AOT function argument of the pointer for the extra return value may cause segmentation fault. Fix the issue reported in #2556. --- core/iwasm/compilation/aot_emit_control.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 2cf51cf67..75d1e622e 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -234,13 +234,15 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, else { /* Store extra return values to function parameters */ if (i != 0) { + LLVMValueRef res; uint32 param_index = func_type->param_count + i; - if (!LLVMBuildStore( - comp_ctx->builder, block->result_phis[i], - LLVMGetParam(func_ctx->func, param_index))) { + if (!(res = LLVMBuildStore( + comp_ctx->builder, block->result_phis[i], + LLVMGetParam(func_ctx->func, param_index)))) { aot_set_last_error("llvm build store failed."); goto fail; } + LLVMSetAlignment(res, 1); } } } @@ -1102,14 +1104,17 @@ aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (block_func->result_count) { /* Store extra result values to function parameters */ for (i = 0; i < block_func->result_count - 1; i++) { + LLVMValueRef res; result_index = block_func->result_count - 1 - i; POP(value, block_func->result_types[result_index]); param_index = func_type->param_count + result_index; - if (!LLVMBuildStore(comp_ctx->builder, value, - LLVMGetParam(func_ctx->func, param_index))) { + if (!(res = LLVMBuildStore( + comp_ctx->builder, value, + LLVMGetParam(func_ctx->func, param_index)))) { aot_set_last_error("llvm build store failed."); goto fail; } + LLVMSetAlignment(res, 1); } /* Return the first result value */ POP(value, block_func->result_types[0]); From 363f08975bc23b53b829d8a3ddf78dec3a8112ab Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 23 Sep 2023 11:28:18 +0900 Subject: [PATCH 31/58] Fix a few issues in "run_wasi_tests.sh: provide stdin by ourselves" (#2582) Apply "provide stdin by ourselves" to the aot case and check the correct exit code. --- tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 03ad9e27a..c4b27390e 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -51,8 +51,8 @@ run_aot_tests () { expected=$(jq .exit_code ${test_json}) fi - ${iwasm} $test_aot - ret=${PIPESTATUS[0]} + python3 ${THIS_DIR}/pipe.py | ${iwasm} $test_aot + ret=${PIPESTATUS[1]} echo "expected=$expected, actual=$ret" if [[ $expected != "" ]] && [[ $expected != $ret ]];then @@ -75,7 +75,7 @@ if [[ $MODE != "aot" ]];then ${THREAD_INTERNAL_TESTS} \ ${LIB_SOCKET_TESTS} \ - ret=${PIPESTATUS[0]} + ret=${PIPESTATUS[1]} TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" python3 test-runner/wasi_test_runner.py \ -r adapters/wasm-micro-runtime.py \ From f474f3d6689ed013ef1753d8b40c5cc967b1db42 Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Mon, 25 Sep 2023 11:40:12 +0100 Subject: [PATCH 32/58] Return __WASI_EINVAL from fd_prestat_dir_name (#2580) Return a WASI error code (rather than a host POSIX one). In addition, there is no need to return an error in the case that the provided buffer is too large. --- .../libc-wasi/sandboxed-system-primitives/src/posix.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index bb6d67a62..fc6bc2839 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -819,12 +819,14 @@ wasmtime_ssp_fd_prestat_dir_name(struct fd_prestats *prestats, __wasi_fd_t fd, rwlock_unlock(&prestats->lock); return error; } - if (path_len != strlen(prestat->dir)) { + + const size_t prestat_dir_len = strlen(prestat->dir); + if (path_len < prestat_dir_len) { rwlock_unlock(&prestats->lock); - return EINVAL; + return __WASI_EINVAL; } - bh_memcpy_s(path, (uint32)path_len, prestat->dir, (uint32)path_len); + bh_memcpy_s(path, (uint32)path_len, prestat->dir, (uint32)prestat_dir_len); rwlock_unlock(&prestats->lock); From 99b47fd33429a4ca999d53d85f5b00302b991191 Mon Sep 17 00:00:00 2001 From: "Alfred E. Neumayer" Date: Mon, 25 Sep 2023 13:00:46 +0200 Subject: [PATCH 33/58] Support AOT compiler with LLVM 17 (#2567) Adapt API usage to new interfaces where applicable, including LLVM function usage, obsoleted llvm::Optional type and removal of unavailable headers. Know issues: - AOT static PGO isn't enabled - LLVM JIT may run failed due to llvm_orc_registerEHFrameSectionWrapper isn't linked into iwasm --- core/iwasm/compilation/aot_llvm.c | 10 +++++++- core/iwasm/compilation/aot_llvm.h | 5 +++- core/iwasm/compilation/aot_llvm_extra.cpp | 27 +++++++++++++++++++++- core/iwasm/compilation/aot_llvm_extra2.cpp | 9 ++++++++ core/iwasm/compilation/aot_orc_extra.cpp | 9 ++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index f4bc8500e..6dc3a0f7d 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -526,12 +526,18 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module, } wasm_runtime_free(params); params = NULL; + +#if LLVM_VERSION_MAJOR < 17 if (aot_target_precheck_can_use_musttail(comp_ctx)) { LLVMSetTailCallKind(retval, LLVMTailCallKindMustTail); } else { LLVMSetTailCallKind(retval, LLVMTailCallKindTail); } +#else + LLVMSetTailCall(retval, true); +#endif + if (ret_type == VOID_TYPE) { if (!LLVMBuildRetVoid(b)) { goto fail; @@ -2172,8 +2178,10 @@ bool aot_compiler_init(void) { /* Initialize LLVM environment */ - +#if LLVM_VERSION_MAJOR < 17 LLVMInitializeCore(LLVMGetGlobalPassRegistry()); +#endif + #if WASM_ENABLE_WAMR_COMPILER != 0 /* Init environment of all targets for AOT compiler */ LLVMInitializeAllTargetInfos(); diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 03994b6c0..b46ac3bd0 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -15,15 +15,18 @@ #include "llvm-c/ExecutionEngine.h" #include "llvm-c/Analysis.h" #include "llvm-c/BitWriter.h" +#if LLVM_VERSION_MAJOR < 17 #include "llvm-c/Transforms/Utils.h" #include "llvm-c/Transforms/Scalar.h" #include "llvm-c/Transforms/Vectorize.h" #include "llvm-c/Transforms/PassManagerBuilder.h" +#include "llvm-c/Initialization.h" +#endif #include "llvm-c/Orc.h" #include "llvm-c/Error.h" #include "llvm-c/Support.h" -#include "llvm-c/Initialization.h" + #include "llvm-c/TargetMachine.h" #include "llvm-c/LLJIT.h" #if WASM_ENABLE_DEBUG_AOT != 0 diff --git a/core/iwasm/compilation/aot_llvm_extra.cpp b/core/iwasm/compilation/aot_llvm_extra.cpp index 898fabd8c..ab6c621a0 100644 --- a/core/iwasm/compilation/aot_llvm_extra.cpp +++ b/core/iwasm/compilation/aot_llvm_extra.cpp @@ -5,11 +5,13 @@ #include #include +#if LLVM_VERSION_MAJOR < 17 #include #include +#include +#endif #include #include -#include #include #include #include @@ -18,7 +20,9 @@ #include #include #include +#if LLVM_VERSION_MAJOR < 17 #include +#endif #include #include #include @@ -30,6 +34,9 @@ #include #include #include +#if LLVM_VERSION_MAJOR >= 17 +#include +#endif #include #include #include @@ -55,6 +62,13 @@ using namespace llvm; using namespace llvm::orc; +#if LLVM_VERSION_MAJOR >= 17 +namespace llvm { +template +using Optional = std::optional; +} +#endif + LLVM_C_EXTERN_C_BEGIN bool @@ -110,7 +124,14 @@ ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM) Memcpy->eraseFromParent(); } else if (MemMoveInst *Memmove = dyn_cast(MemCall)) { +#if LLVM_VERSION_MAJOR >= 17 + Function *ParentFunc = Memmove->getParent()->getParent(); + const TargetTransformInfo &TTI = + AM.getResult(*ParentFunc); + expandMemMoveAsLoop(Memmove, TTI); +#else expandMemMoveAsLoop(Memmove); +#endif Memmove->eraseFromParent(); } else if (MemSetInst *Memset = dyn_cast(MemCall)) { @@ -181,6 +202,9 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module) #else Optional PGO = llvm::None; #endif + +// TODO +#if LLVM_VERSION_MAJOR < 17 if (comp_ctx->enable_llvm_pgo) { /* Disable static counter allocation for value profiler, it will be allocated by runtime */ @@ -191,6 +215,7 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module) else if (comp_ctx->use_prof_file) { PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse); } +#endif #ifdef DEBUG_PASS PassInstrumentationCallbacks PIC; diff --git a/core/iwasm/compilation/aot_llvm_extra2.cpp b/core/iwasm/compilation/aot_llvm_extra2.cpp index 42e53ddfa..8364e5ebf 100644 --- a/core/iwasm/compilation/aot_llvm_extra2.cpp +++ b/core/iwasm/compilation/aot_llvm_extra2.cpp @@ -4,8 +4,10 @@ */ #include +#if LLVM_VERSION_MAJOR < 17 #include #include +#endif #include #if LLVM_VERSION_MAJOR >= 14 #include @@ -18,6 +20,13 @@ #include "aot_llvm_extra2.h" +#if LLVM_VERSION_MAJOR >= 17 +namespace llvm { +template +using Optional = std::optional; +} +#endif + static llvm::Optional convert(LLVMRelocMode reloc_mode) { diff --git a/core/iwasm/compilation/aot_orc_extra.cpp b/core/iwasm/compilation/aot_orc_extra.cpp index 9cfe331e5..51d61bf3c 100644 --- a/core/iwasm/compilation/aot_orc_extra.cpp +++ b/core/iwasm/compilation/aot_orc_extra.cpp @@ -8,8 +8,10 @@ #include "llvm-c/OrcEE.h" #include "llvm-c/TargetMachine.h" +#if LLVM_VERSION_MAJOR < 17 #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#endif #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" @@ -21,6 +23,13 @@ #include "aot_orc_extra.h" #include "aot.h" +#if LLVM_VERSION_MAJOR >= 17 +namespace llvm { +template +using Optional = std::optional; +} +#endif + using namespace llvm; using namespace llvm::orc; using GlobalValueSet = std::set; From efb5cca93d6a72da9f23de59e573326a9c5ff8bc Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 25 Sep 2023 20:25:01 +0800 Subject: [PATCH 34/58] Fix compile error of tsf benchmark (#2588) Explicitly declare readdir_r in gpc_code_gen_util.c. --- tests/benchmarks/jetstream/tsf.patch | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/jetstream/tsf.patch b/tests/benchmarks/jetstream/tsf.patch index e52c3cdc5..98355b08c 100644 --- a/tests/benchmarks/jetstream/tsf.patch +++ b/tests/benchmarks/jetstream/tsf.patch @@ -1,6 +1,18 @@ +diff -urN tsf-src-org/gpc_code_gen_util.c tsf-src/gpc_code_gen_util.c +--- tsf-src-org/gpc_code_gen_util.c 2023-09-21 11:12:40.211166472 +0800 ++++ tsf-src/gpc_code_gen_util.c 2023-09-21 11:09:13.643170967 +0800 +@@ -34,6 +34,8 @@ + #include + #include + ++int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); ++ + /* code generation debugging */ + + /* NOTE: It is now the case that the count may be incremented multiple times, diff -urN tsf-src-org/tsf_internal.h tsf-src/tsf_internal.h ---- tsf-src-org/tsf_internal.h 2023-03-31 10:49:45.000000000 +0800 -+++ tsf-src/tsf_internal.h 2023-05-11 08:18:35.000000000 +0800 +--- tsf-src-org/tsf_internal.h 2023-09-21 11:11:50.843167546 +0800 ++++ tsf-src/tsf_internal.h 2023-09-21 11:06:53.031174027 +0800 @@ -429,6 +429,7 @@ #endif tsf_fsdb_connection_t *connection; @@ -10,15 +22,15 @@ diff -urN tsf-src-org/tsf_internal.h tsf-src/tsf_internal.h } u; tsf_limits_t *limits; diff -urN tsf-src-org/tsf_ir_speed.c tsf-src/tsf_ir_speed.c ---- tsf-src-org/tsf_ir_speed.c 2023-03-31 10:49:45.000000000 +0800 -+++ tsf-src/tsf_ir_speed.c 2023-05-11 08:18:35.000000000 +0800 +--- tsf-src-org/tsf_ir_speed.c 2023-09-21 11:12:15.699167005 +0800 ++++ tsf-src/tsf_ir_speed.c 2023-09-21 11:06:53.031174027 +0800 @@ -63,6 +63,9 @@ Program_t *program; unsigned elementIndex; - + + if (!(programIndex % 100)) + printf("##programIndex: %u\n", programIndex); + CS(program = tsf_region_create(sizeof(Program_t))); - + program->globals.len = numDecls + numDefns; From 94f276eab0c296db1ac0486322e2094238557501 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 26 Sep 2023 10:20:13 +0900 Subject: [PATCH 35/58] test_wamr.sh: Bump wasi-testsuite version (#2568) On posix-like platforms, the rest of wasi-threads tests should pass after the recent changes including the following PRs: #2516, #2524, #2529, #2571, #2576 and #2582. --- tests/wamr-test-suites/test_wamr.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 06231f1e1..11650651c 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -55,7 +55,8 @@ PLATFORM=$(uname -s | tr A-Z a-z) PARALLELISM=0 ENABLE_QEMU=0 QEMU_FIRMWARE="" -WASI_TESTSUITE_COMMIT="aca78d919355ae00af141e6741a439039615b257" +# prod/testsuite-all branch +WASI_TESTSUITE_COMMIT="cf64229727f71043d5849e73934e249e12cb9e06" while getopts ":s:cabgvt:m:MCpSXxwPGQF:" opt do From 913a1414ad8351385370948784490fa66aa4da69 Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Tue, 26 Sep 2023 02:31:32 +0100 Subject: [PATCH 36/58] Add support for closing/renumbering preopen fds (#2578) There doesn't appear to be a clear reason not to support this behavior. It seems it was disallowed previously as a precaution. See https://github.com/bytecodealliance/wasmtime/commit/67e2e57b02cd244c004379690aa56d3d5e187153 for more context. --- .../sandboxed-system-primitives/src/posix.c | 152 +++++++++++++----- 1 file changed, 108 insertions(+), 44 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index fc6bc2839..eda65b8da 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -339,7 +339,7 @@ fd_prestats_init(struct fd_prestats *pt) // Grows the preopened resource table to a required lower bound and a // minimum number of free preopened resource table entries. -static bool +static __wasi_errno_t fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr) REQUIRES_EXCLUSIVE(pt->lock) { @@ -353,7 +353,7 @@ fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr) struct fd_prestat *prestats = wasm_runtime_malloc((uint32)(sizeof(*prestats) * size)); if (prestats == NULL) - return false; + return __WASI_ENOMEM; if (pt->prestats && pt->size > 0) { bh_memcpy_s(prestats, (uint32)(sizeof(*prestats) * size), @@ -369,27 +369,39 @@ fd_prestats_grow(struct fd_prestats *pt, size_t min, size_t incr) pt->prestats = prestats; pt->size = size; } - return true; + return __WASI_ESUCCESS; +} + +static __wasi_errno_t +fd_prestats_insert_locked(struct fd_prestats *pt, const char *dir, + __wasi_fd_t fd) +{ + // Grow the preopened resource table if needed. + __wasi_errno_t error = fd_prestats_grow(pt, fd, 1); + + if (error != __WASI_ESUCCESS) { + return error; + } + + pt->prestats[fd].dir = bh_strdup(dir); + + if (pt->prestats[fd].dir == NULL) + return __WASI_ENOMEM; + + return __WASI_ESUCCESS; } // Inserts a preopened resource record into the preopened resource table. bool fd_prestats_insert(struct fd_prestats *pt, const char *dir, __wasi_fd_t fd) { - // Grow the preopened resource table if needed. rwlock_wrlock(&pt->lock); - if (!fd_prestats_grow(pt, fd, 1)) { - rwlock_unlock(&pt->lock); - return false; - } - pt->prestats[fd].dir = bh_strdup(dir); + __wasi_errno_t error = fd_prestats_insert_locked(pt, dir, fd); + rwlock_unlock(&pt->lock); - if (pt->prestats[fd].dir == NULL) - return false; - - return true; + return error == __WASI_ESUCCESS; } // Looks up a preopened resource table entry by number. @@ -408,6 +420,24 @@ fd_prestats_get_entry(struct fd_prestats *pt, __wasi_fd_t fd, return 0; } +// Remove a preopened resource record from the preopened resource table by +// number +static __wasi_errno_t +fd_prestats_remove_entry(struct fd_prestats *pt, __wasi_fd_t fd) +{ + // Test for file descriptor existence. + if (fd >= pt->size) + return __WASI_EBADF; + struct fd_prestat *prestat = &pt->prestats[fd]; + + if (prestat->dir != NULL) { + wasm_runtime_free((void *)prestat->dir); + prestat->dir = NULL; + } + + return __WASI_ESUCCESS; +} + struct fd_object { struct refcount refcount; __wasi_filetype_t type; @@ -837,25 +867,15 @@ __wasi_errno_t wasmtime_ssp_fd_close(wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, __wasi_fd_t fd) { - // Don't allow closing a pre-opened resource. - // TODO: Eventually, we do want to permit this, once libpreopen in - // userspace is capable of removing entries from its tables as well. - { - rwlock_rdlock(&prestats->lock); - struct fd_prestat *prestat; - __wasi_errno_t error = fd_prestats_get_entry(prestats, fd, &prestat); - rwlock_unlock(&prestats->lock); - if (error == 0) { - return __WASI_ENOTSUP; - } - } - // Validate the file descriptor. struct fd_table *ft = curfds; rwlock_wrlock(&ft->lock); + rwlock_wrlock(&prestats->lock); + struct fd_entry *fe; __wasi_errno_t error = fd_table_get_entry(ft, fd, 0, 0, &fe); if (error != 0) { + rwlock_unlock(&prestats->lock); rwlock_unlock(&ft->lock); return error; } @@ -863,9 +883,20 @@ wasmtime_ssp_fd_close(wasm_exec_env_t exec_env, struct fd_table *curfds, // Remove it from the file descriptor table. struct fd_object *fo; fd_table_detach(ft, fd, &fo); + + // Remove it from the preopened resource table if it exists + error = fd_prestats_remove_entry(prestats, fd); + + rwlock_unlock(&prestats->lock); rwlock_unlock(&ft->lock); fd_object_release(exec_env, fo); - return 0; + + // Ignore the error if there is no preopen associated with this fd + if (error == __WASI_EBADF) { + return __WASI_ESUCCESS; + } + + return error; } // Look up a file descriptor object in a locked file descriptor table @@ -1081,33 +1112,21 @@ wasmtime_ssp_fd_renumber(wasm_exec_env_t exec_env, struct fd_table *curfds, struct fd_prestats *prestats, __wasi_fd_t from, __wasi_fd_t to) { - // Don't allow renumbering over a pre-opened resource. - // TODO: Eventually, we do want to permit this, once libpreopen in - // userspace is capable of removing entries from its tables as well. - { - rwlock_rdlock(&prestats->lock); - struct fd_prestat *prestat; - __wasi_errno_t error = fd_prestats_get_entry(prestats, to, &prestat); - if (error != 0) { - error = fd_prestats_get_entry(prestats, from, &prestat); - } - rwlock_unlock(&prestats->lock); - if (error == 0) { - return __WASI_ENOTSUP; - } - } - struct fd_table *ft = curfds; rwlock_wrlock(&ft->lock); + rwlock_wrlock(&prestats->lock); + struct fd_entry *fe_from; __wasi_errno_t error = fd_table_get_entry(ft, from, 0, 0, &fe_from); if (error != 0) { + rwlock_unlock(&prestats->lock); rwlock_unlock(&ft->lock); return error; } struct fd_entry *fe_to; error = fd_table_get_entry(ft, to, 0, 0, &fe_to); if (error != 0) { + rwlock_unlock(&prestats->lock); rwlock_unlock(&ft->lock); return error; } @@ -1124,8 +1143,53 @@ wasmtime_ssp_fd_renumber(wasm_exec_env_t exec_env, struct fd_table *curfds, fd_object_release(exec_env, fo); --ft->used; + // Handle renumbering of any preopened resources + struct fd_prestat *prestat_from; + __wasi_errno_t prestat_from_error = + fd_prestats_get_entry(prestats, from, &prestat_from); + + struct fd_prestat *prestat_to; + __wasi_errno_t prestat_to_error = + fd_prestats_get_entry(prestats, to, &prestat_to); + + // Renumbering over two preopened resources. + if (prestat_from_error == __WASI_ESUCCESS + && prestat_to_error == __WASI_ESUCCESS) { + (void)fd_prestats_remove_entry(prestats, to); + + error = fd_prestats_insert_locked(prestats, prestat_from->dir, to); + + if (error == __WASI_ESUCCESS) { + (void)fd_prestats_remove_entry(prestats, from); + } + else { + (void)fd_prestats_remove_entry(prestats, to); + } + } + // Renumbering from a non-preopened fd to a preopened fd. In this case, we + // can't a keep the destination fd entry in the preopened table so remove + // it entirely. + else if (prestat_from_error != __WASI_ESUCCESS + && prestat_to_error == __WASI_ESUCCESS) { + (void)fd_prestats_remove_entry(prestats, to); + } + // Renumbering from a preopened fd to a non-preopened fd + else if (prestat_from_error == __WASI_ESUCCESS + && prestat_to_error != __WASI_ESUCCESS) { + error = fd_prestats_insert_locked(prestats, prestat_from->dir, to); + + if (error == __WASI_ESUCCESS) { + (void)fd_prestats_remove_entry(prestats, from); + } + else { + (void)fd_prestats_remove_entry(prestats, to); + } + } + + rwlock_unlock(&prestats->lock); rwlock_unlock(&ft->lock); - return 0; + + return error; } __wasi_errno_t From b62262209651ba18b59ba19170038b9ea12aa024 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 26 Sep 2023 11:00:33 +0900 Subject: [PATCH 37/58] samples/inst-context-threads: Add a brief explanation (#2592) --- samples/inst-context-threads/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/inst-context-threads/README.md b/samples/inst-context-threads/README.md index 43b13c66b..d64cbff52 100644 --- a/samples/inst-context-threads/README.md +++ b/samples/inst-context-threads/README.md @@ -1,4 +1,5 @@ -The "inst-context" sample project -================================= +The "inst-context-threads" sample project +========================================= -This sample demonstrates module instance context API. +This sample demonstrates some interactions between +module instance context API and wasi-threads. From 6382162711a9cfaedc63de9065b0bc6eda8123f3 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 26 Sep 2023 10:17:54 +0800 Subject: [PATCH 38/58] Fix loader push_pop_frame_ref_offset (#2590) `wasm_loader_push_pop_frame_offset` may pop n operands by using `loader_ctx->stack_cell_num` to check whether the operand can be popped or not. While `loader_ctx->stack_cell_num` is updated in the later `wasm_loader_push_pop_frame_ref`, the check may fail if the stack is in polymorphic state and lead to `ctx->frame_offset` underflow. Fix issue #2577 and #2586. --- core/iwasm/interpreter/wasm_loader.c | 45 ++++++++++------------- core/iwasm/interpreter/wasm_mini_loader.c | 43 ++++++++++------------ 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index c775ee6c0..130ad4392 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -5476,6 +5476,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf, return true; } +#if WASM_ENABLE_FAST_INTERP == 0 static bool wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, uint8 type_push, uint8 type_pop, char *error_buf, @@ -5490,6 +5491,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, return false; return true; } +#endif static bool wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, @@ -6166,27 +6168,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type, return true; } -static bool -wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt, - uint8 type_push, uint8 type_pop, - bool disable_emit, int16 operand_offset, - char *error_buf, uint32 error_buf_size) -{ - uint8 i; - - for (i = 0; i < pop_cnt; i++) { - if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, - error_buf_size)) - return false; - } - if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit, - operand_offset, error_buf, - error_buf_size)) - return false; - - return true; -} - static bool wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, bool disable_emit, int16 operand_offset, @@ -6220,12 +6201,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt, bool disable_emit, int16 operand_offset, char *error_buf, uint32 error_buf_size) { - if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop, - disable_emit, operand_offset, - error_buf, error_buf_size)) + uint8 i; + + for (i = 0; i < pop_cnt; i++) { + if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, + error_buf_size)) + return false; + + if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf, + error_buf_size)) + return false; + } + + if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit, + operand_offset, error_buf, + error_buf_size)) return false; - if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop, - error_buf, error_buf_size)) + + if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size)) return false; return true; diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 9f568e132..d16bc1a24 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -3937,6 +3937,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf, return true; } +#if WASM_ENABLE_FAST_INTERP == 0 static bool wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, uint8 type_push, uint8 type_pop, char *error_buf, @@ -3951,6 +3952,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt, return false; return true; } +#endif static bool wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, @@ -4608,25 +4610,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type, return true; } -static bool -wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt, - uint8 type_push, uint8 type_pop, - bool disable_emit, int16 operand_offset, - char *error_buf, uint32 error_buf_size) -{ - for (int i = 0; i < pop_cnt; i++) { - if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, - error_buf_size)) - return false; - } - if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit, - operand_offset, error_buf, - error_buf_size)) - return false; - - return true; -} - static bool wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, bool disable_emit, int16 operand_offset, @@ -4660,12 +4643,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt, bool disable_emit, int16 operand_offset, char *error_buf, uint32 error_buf_size) { - if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop, - disable_emit, operand_offset, - error_buf, error_buf_size)) + uint8 i; + + for (i = 0; i < pop_cnt; i++) { + if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf, + error_buf_size)) + return false; + + if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf, + error_buf_size)) + return false; + } + + if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit, + operand_offset, error_buf, + error_buf_size)) return false; - if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop, - error_buf, error_buf_size)) + + if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size)) return false; return true; From ade73f6142a1a11202053219b840580eeb24750e Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 26 Sep 2023 16:13:12 +0800 Subject: [PATCH 39/58] Fix compilation error on Android platform (#2594) The CI might use clang-17 to build iwasm for Android platform and it may report compilation error: https://github.com/bytecodealliance/wasm-micro-runtime/actions/runs/6308980430/job/17128073777 /home/runner/work/wasm-micro-runtime/wasm-micro-runtime/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c:45:19: error: call to undeclared function 'preadv'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] ssize_t ret = preadv(fd, iov, iovcnt, offset); ^ Explicitly declare preadv and pwritev in android platform header file to resolve it. --- core/shared/platform/android/platform_internal.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/shared/platform/android/platform_internal.h b/core/shared/platform/android/platform_internal.h index d718a2d7d..c28a7b9be 100644 --- a/core/shared/platform/android/platform_internal.h +++ b/core/shared/platform/android/platform_internal.h @@ -139,16 +139,12 @@ seekdir(DIR *__dir, long __location); #endif -#if __ANDROID_API__ < 24 - ssize_t preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset); ssize_t pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset); -#endif - #ifdef __cplusplus } #endif From a50a4384613a18d21c5ecb5fec2482775607fc91 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 26 Sep 2023 19:59:48 +0800 Subject: [PATCH 40/58] Ignore handling SIG_DFL/SIG_IGN for previous sig action (#2589) --- core/shared/platform/common/posix/posix_thread.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index a0b184405..a7bdc6d10 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -543,14 +543,12 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext) if (prev_sig_act && (prev_sig_act->sa_flags & SA_SIGINFO)) { prev_sig_act->sa_sigaction(sig_num, sig_info, sig_ucontext); } - else if (prev_sig_act && (void *)prev_sig_act->sa_handler == SIG_DFL) { - /* Default action */ - sigaction(sig_num, prev_sig_act, NULL); - } - else if (prev_sig_act && (void *)prev_sig_act->sa_handler == SIG_IGN) { - /* Ignore this signal */ - } - else if (prev_sig_act && prev_sig_act->sa_handler) { + else if (prev_sig_act + && prev_sig_act->sa_handler + /* Filter out SIG_DFL and SIG_IGN here, they will + run into the else branch below */ + && (void *)prev_sig_act->sa_handler != SIG_DFL + && (void *)prev_sig_act->sa_handler != SIG_IGN) { prev_sig_act->sa_handler(sig_num); } /* Output signal info and then crash if signal is unhandled */ From fff0e2ad1cf9d5749f0e92582167353af995f730 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 27 Sep 2023 15:41:48 +0800 Subject: [PATCH 41/58] Fix nightly run sanitizer error in Fast JIT (#2601) Suppress a sanitizer integer overflow error in signed integer add operation in Fast JIT. --- core/iwasm/fast-jit/fe/jit_emit_numberic.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/iwasm/fast-jit/fe/jit_emit_numberic.c b/core/iwasm/fast-jit/fe/jit_emit_numberic.c index 03491e691..6a1e93ede 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_numberic.c +++ b/core/iwasm/fast-jit/fe/jit_emit_numberic.c @@ -298,7 +298,15 @@ fail: /* macros for integer binary operations (ibinop) */ +#if defined(__GNUC__) +#define NO_SANITIZER_INTEGER \ + __attribute__((no_sanitize("signed-integer-overflow"))) +#else +#define NO_SANITIZER_INTEGER +#endif + #define __DEF_BI_INT_CONST_OPS(bits, opname, op) \ + NO_SANITIZER_INTEGER \ static int##bits do_i##bits##_const_##opname(int##bits lhs, int##bits rhs) \ { \ return lhs op rhs; \ From 79b27c193461db91e00d5a9688c5697bb5334a8d Mon Sep 17 00:00:00 2001 From: dongsheng28849455 <68947925+dongsheng28849455@users.noreply.github.com> Date: Thu, 28 Sep 2023 08:56:11 +0800 Subject: [PATCH 42/58] Support muti-module for AOT mode (#2482) Support muti-module for AOT mode, currently only implement the multi-module's function import feature for AOT, the memory/table/ global import are not implemented yet. And update wamr-test-suites scripts, multi-module sample and some CIs accordingly. --- .../compilation_on_android_ubuntu.yml | 33 +- .github/workflows/compilation_on_macos.yml | 4 +- .github/workflows/nightly_run.yml | 35 +- core/iwasm/aot/aot_loader.c | 110 ++++- core/iwasm/aot/aot_runtime.c | 89 +++- core/iwasm/aot/aot_runtime.h | 14 + core/iwasm/common/wasm_runtime_common.c | 379 +++++++++++++++++- core/iwasm/common/wasm_runtime_common.h | 32 ++ core/iwasm/include/wasm_export.h | 2 +- core/iwasm/interpreter/wasm_loader.c | 198 +-------- core/iwasm/interpreter/wasm_runtime.c | 88 +--- core/iwasm/interpreter/wasm_runtime.h | 6 +- product-mini/platforms/posix/main.c | 23 +- product-mini/platforms/windows/main.c | 27 +- samples/multi-module/CMakeLists.txt | 45 ++- samples/multi-module/README.md | 20 + samples/multi-module/src/main.c | 64 +-- .../muti_module_aot_ignore_cases.patch | 174 ++++++++ .../spec-test-script/runtest.py | 11 + tests/wamr-test-suites/test_wamr.sh | 7 +- 20 files changed, 1018 insertions(+), 343 deletions(-) create mode 100644 samples/multi-module/README.md create mode 100644 tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 927ef4d75..3c5b4e35e 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -328,7 +328,12 @@ jobs: working-directory: samples/wasm-c-api build_samples_others: - needs: [build_iwasm] + needs: + [ + build_iwasm, + build_llvm_libraries_on_ubuntu_2204, + build_wamrc, + ] runs-on: ${{ matrix.os }} strategy: matrix: @@ -341,6 +346,9 @@ jobs: [ "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz", ] + include: + - os: ubuntu-22.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} steps: - name: checkout uses: actions/checkout@v3 @@ -358,7 +366,23 @@ jobs: sudo wget ${{ matrix.wabt_release }} sudo tar -xzf wabt-1.0.31-*.tar.gz sudo mv wabt-1.0.31 wabt - + - name: Get LLVM libraries + id: retrieve_llvm_libs + uses: actions/cache@v3 + with: + path: | + ./core/deps/llvm/build/bin + ./core/deps/llvm/build/include + ./core/deps/llvm/build/lib + ./core/deps/llvm/build/libexec + ./core/deps/llvm/build/share + key: ${{ matrix.llvm_cache_key }} + - name: Build wamrc + run: | + mkdir build && cd build + cmake .. + cmake --build . --config Release --parallel 4 + working-directory: wamr-compiler - name: Build Sample [basic] run: | cd samples/basic @@ -385,9 +409,10 @@ jobs: run: | cd samples/multi-module mkdir build && cd build - cmake .. + cmake .. -DWAMR_BUILD_AOT=1 cmake --build . --config Release --parallel 4 - ./multi_module + ./multi_module mC.wasm + ./multi_module mC.aot - name: Build Sample [spawn-thread] run: | diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index aaa97d038..f06833185 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -245,7 +245,7 @@ jobs: working-directory: samples/wasm-c-api build_samples_others: - needs: [build_iwasm] + needs: [build_iwasm, build_wamrc] runs-on: ${{ matrix.os }} strategy: matrix: @@ -304,7 +304,7 @@ jobs: mkdir build && cd build cmake .. cmake --build . --config Release --parallel 4 - ./multi_module + ./multi_module mC.wasm - name: Build Sample [spawn-thread] run: | diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index adedd1ef7..1cf4b51e3 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -380,7 +380,12 @@ jobs: working-directory: samples/wasm-c-api build_samples_others: - needs: [build_iwasm] + needs: + [ + build_iwasm, + build_llvm_libraries_on_ubuntu_2004, + build_wamrc, + ] runs-on: ${{ matrix.os }} strategy: matrix: @@ -393,6 +398,9 @@ jobs: [ "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz", ] + include: + - os: ubuntu-20.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} steps: - name: checkout uses: actions/checkout@v3 @@ -409,6 +417,26 @@ jobs: sudo wget ${{ matrix.wabt_release }} sudo tar -xzf wabt-1.0.31-*.tar.gz sudo mv wabt-1.0.31 wabt + + - name: Get LLVM libraries + id: retrieve_llvm_libs + uses: actions/cache@v3 + with: + path: | + ./core/deps/llvm/build/bin + ./core/deps/llvm/build/include + ./core/deps/llvm/build/lib + ./core/deps/llvm/build/libexec + ./core/deps/llvm/build/share + key: ${{ matrix.llvm_cache_key }} + + - name: Build wamrc + run: | + mkdir build && cd build + cmake -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}" .. + cmake --build . --config Release --parallel 4 + working-directory: wamr-compiler + - name: Build Sample [basic] run: | cd samples/basic @@ -432,9 +460,10 @@ jobs: run: | cd samples/multi-module mkdir build && cd build - cmake .. + cmake .. -DWAMR_BUILD_AOT=1 cmake --build . --config Release --parallel 4 - ./multi_module + ./multi_module mC.wasm + ./multi_module mC.aot - name: Build Sample [spawn-thread] run: | cd samples/spawn-thread diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 0ce2cf9da..b5fa33c0c 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -558,6 +558,56 @@ str2uint32(const char *buf, uint32 *p_res); static bool str2uint64(const char *buf, uint64 *p_res); +#if WASM_ENABLE_MULTI_MODULE != 0 +static void * +aot_loader_resolve_function(const char *module_name, const char *function_name, + const AOTFuncType *expected_function_type, + char *error_buf, uint32 error_buf_size) +{ + WASMModuleCommon *module_reg; + void *function = NULL; + AOTExport *export = NULL; + AOTModule *module = NULL; + AOTFuncType *target_function_type = NULL; + + module_reg = wasm_runtime_find_module_registered(module_name); + if (!module_reg || module_reg->module_type != Wasm_Module_AoT) { + LOG_DEBUG("can not find a module named %s for function %s", module_name, + function_name); + set_error_buf(error_buf, error_buf_size, "unknown import"); + return NULL; + } + + module = (AOTModule *)module_reg; + export = loader_find_export(module_reg, module_name, function_name, + EXPORT_KIND_FUNC, error_buf, error_buf_size); + if (!export) { + return NULL; + } + + /* resolve function type and function */ + if (export->index < module->import_func_count) { + target_function_type = module->import_funcs[export->index].func_type; + function = module->import_funcs[export->index].func_ptr_linked; + } + else { + target_function_type = + module->func_types[module->func_type_indexes + [export->index - module->import_func_count]]; + function = + (module->func_ptrs[export->index - module->import_func_count]); + } + /* check function type */ + if (!wasm_type_equal(expected_function_type, target_function_type)) { + LOG_DEBUG("%s.%s failed the type check", module_name, function_name); + set_error_buf(error_buf, error_buf_size, "incompatible import type"); + return NULL; + } + return function; +} + +#endif /* end of WASM_ENABLE_MULTI_MODULE */ + static bool load_native_symbol_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, @@ -1357,11 +1407,16 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, char *error_buf, uint32 error_buf_size) { - const char *module_name, *field_name; + char *module_name, *field_name; const uint8 *buf = *p_buf; AOTImportFunc *import_funcs; uint64 size; uint32 i; +#if WASM_ENABLE_MULTI_MODULE != 0 + AOTModule *sub_module = NULL; + AOTFunc *linked_func = NULL; + WASMType *declare_func_type = NULL; +#endif /* Allocate memory */ size = sizeof(AOTImportFunc) * (uint64)module->import_func_count; @@ -1377,17 +1432,46 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, set_error_buf(error_buf, error_buf_size, "unknown type"); return false; } + +#if WASM_ENABLE_MULTI_MODULE != 0 + declare_func_type = module->func_types[import_funcs[i].func_type_index]; + read_string(buf, buf_end, module_name); + read_string(buf, buf_end, field_name); + + import_funcs[i].module_name = module_name; + import_funcs[i].func_name = field_name; + linked_func = wasm_native_resolve_symbol( + module_name, field_name, declare_func_type, + &import_funcs[i].signature, &import_funcs[i].attachment, + &import_funcs[i].call_conv_raw); + if (!linked_func) { + if (!wasm_runtime_is_built_in_module(module_name)) { + sub_module = (AOTModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)module, module_name, error_buf, + error_buf_size); + if (!sub_module) { + return false; + } + } + linked_func = aot_loader_resolve_function( + module_name, field_name, declare_func_type, error_buf, + error_buf_size); + } + import_funcs[i].func_ptr_linked = linked_func; + import_funcs[i].func_type = declare_func_type; + +#else import_funcs[i].func_type = module->func_types[import_funcs[i].func_type_index]; read_string(buf, buf_end, import_funcs[i].module_name); read_string(buf, buf_end, import_funcs[i].func_name); - module_name = import_funcs[i].module_name; field_name = import_funcs[i].func_name; import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol( module_name, field_name, import_funcs[i].func_type, &import_funcs[i].signature, &import_funcs[i].attachment, &import_funcs[i].call_conv_raw); +#endif #if WASM_ENABLE_LIBC_WASI != 0 if (!strcmp(import_funcs[i].module_name, "wasi_unstable") @@ -2872,12 +2956,17 @@ create_module(char *error_buf, uint32 error_buf_size) AOTModule *module = loader_malloc(sizeof(AOTModule), error_buf, error_buf_size); + bh_list_status ret; if (!module) { return NULL; } - module->module_type = Wasm_Module_AoT; - +#if WASM_ENABLE_MULTI_MODULE != 0 + module->import_module_list = &module->import_module_list_head; + ret = bh_list_init(module->import_module_list); + bh_assert(ret == BH_LIST_SUCCESS); +#endif + (void)ret; return module; } @@ -3201,6 +3290,19 @@ aot_unload(AOTModule *module) if (module->const_str_set) bh_hash_map_destroy(module->const_str_set); +#if WASM_ENABLE_MULTI_MODULE != 0 + /* just release the sub module list */ + if (module->import_module_list) { + WASMRegisteredModule *node = + bh_list_first_elem(module->import_module_list); + while (node) { + WASMRegisteredModule *next = bh_list_elem_next(node); + bh_list_remove(module->import_module_list, node); + wasm_runtime_free(node); + node = next; + } + } +#endif if (module->code && !module->is_indirect_mode) { /* The layout is: literal size + literal + code (with plt table) */ diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 55cf2d985..abd4539be 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1091,6 +1091,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, uint8 *p; uint32 i, extra_info_offset; const bool is_sub_inst = parent != NULL; +#if WASM_ENABLE_MULTI_MODULE != 0 + bool ret = false; +#endif /* Check heap size */ heap_size = align_uint(heap_size, 8); @@ -1134,6 +1137,18 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent, module_inst->e = (WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset); +#if WASM_ENABLE_MULTI_MODULE != 0 + ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list = + &((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list_head; + ret = wasm_runtime_sub_module_instantiate( + (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst, + stack_size, heap_size, error_buf, error_buf_size); + if (!ret) { + LOG_DEBUG("build a sub module list failed"); + goto fail; + } +#endif + /* Initialize global info */ p = (uint8 *)module_inst + module_inst_struct_size + module_inst_mem_inst_size; @@ -1256,6 +1271,11 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) } #endif +#if WASM_ENABLE_MULTI_MODULE != 0 + wasm_runtime_sub_module_deinstantiate( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (module_inst->tables) wasm_runtime_free(module_inst->tables); @@ -1411,10 +1431,43 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, unsigned argc, uint32 argv[]) { AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst; - AOTFuncType *func_type = function->u.func.func_type; + AOTFuncType *func_type = function->is_import_func + ? function->u.func_import->func_type + : function->u.func.func_type; uint32 result_count = func_type->result_count; uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0; bool ret; + void *func_ptr = function->is_import_func + ? function->u.func_import->func_ptr_linked + : function->u.func.func_ptr; +#if WASM_ENABLE_MULTI_MODULE != 0 + bh_list *sub_module_list_node = NULL; + const char *sub_inst_name = NULL; + const char *func_name = function->u.func_import->module_name; + if (function->is_import_func) { + sub_module_list_node = + ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list; + sub_module_list_node = bh_list_first_elem(sub_module_list_node); + while (sub_module_list_node) { + sub_inst_name = + ((AOTSubModInstNode *)sub_module_list_node)->module_name; + if (strcmp(sub_inst_name, func_name) == 0) { + exec_env = wasm_runtime_get_exec_env_singleton( + (WASMModuleInstanceCommon *)((AOTSubModInstNode *) + sub_module_list_node) + ->module_inst); + module_inst = (AOTModuleInstance *)exec_env->module_inst; + break; + } + sub_module_list_node = bh_list_elem_next(sub_module_list_node); + } + if (exec_env == NULL) { + wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst, + "create singleton exec_env failed"); + return false; + } + } +#endif if (argc < func_type->param_cell_num) { char buf[108]; @@ -1436,8 +1489,7 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, #endif /* func pointer was looked up previously */ - bh_assert(function->u.func.func_ptr != NULL); - + bh_assert(func_ptr != NULL); /* set thread handle and stack boundary */ wasm_exec_env_set_thread_info(exec_env); @@ -1546,8 +1598,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, } #endif - ret = invoke_native_internal(exec_env, function->u.func.func_ptr, - func_type, NULL, NULL, argv, argc, argv); + ret = invoke_native_internal(exec_env, func_ptr, func_type, NULL, NULL, + argv, argc, argv); #if WASM_ENABLE_DUMP_CALL_STACK != 0 if (aot_copy_exception(module_inst, NULL)) { @@ -1939,7 +1991,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, void *attachment; char buf[96]; bool ret = false; - +#if WASM_ENABLE_MULTI_MODULE != 0 + bh_list *sub_module_list_node = NULL; + const char *sub_inst_name = NULL; +#endif bh_assert(func_idx < aot_module->import_func_count); import_func = aot_module->import_funcs + func_idx; @@ -1963,6 +2018,28 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, } else if (!import_func->call_conv_raw) { signature = import_func->signature; +#if WASM_ENABLE_MULTI_MODULE != 0 + sub_module_list_node = + ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list; + sub_module_list_node = bh_list_first_elem(sub_module_list_node); + while (sub_module_list_node) { + sub_inst_name = + ((AOTSubModInstNode *)sub_module_list_node)->module_name; + if (strcmp(sub_inst_name, import_func->module_name) == 0) { + exec_env = wasm_runtime_get_exec_env_singleton( + (WASMModuleInstanceCommon *)((AOTSubModInstNode *) + sub_module_list_node) + ->module_inst); + break; + } + sub_module_list_node = bh_list_elem_next(sub_module_list_node); + } + if (exec_env == NULL) { + wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst, + "create singleton exec_env failed"); + goto fail; + } +#endif ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 4358e3079..35c78bfa0 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -90,6 +90,10 @@ typedef struct AOTFunctionInstance { typedef struct AOTModuleInstanceExtra { DefPointer(const uint32 *, stack_sizes); WASMModuleInstanceExtraCommon common; +#if WASM_ENABLE_MULTI_MODULE != 0 + bh_list sub_module_inst_list_head; + bh_list *sub_module_inst_list; +#endif } AOTModuleInstanceExtra; #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) @@ -229,6 +233,12 @@ typedef struct AOTModule { WASIArguments wasi_args; bool import_wasi_api; #endif + +#if WASM_ENABLE_MULTI_MODULE != 0 + /* TODO: add mutex for mutli-thread? */ + bh_list import_module_list_head; + bh_list *import_module_list; +#endif #if WASM_ENABLE_DEBUG_AOT != 0 void *elf_hdr; uint32 elf_size; @@ -247,6 +257,10 @@ typedef struct AOTModule { #define AOTTableInstance WASMTableInstance #define AOTModuleInstance WASMModuleInstance +#if WASM_ENABLE_MULTI_MODULE != 0 +#define AOTSubModInstNode WASMSubModInstNode +#endif + /* Target info, read from ELF header of object file */ typedef struct AOTTargetInfo { /* Binary type, elf32l/elf32b/elf64l/elf64b */ diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 353985b13..d5c40d6e9 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -125,6 +125,36 @@ runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst, return mem; } +#if WASM_ENABLE_MULTI_MODULE != 0 +/* + TODO: + Let loader_malloc be a general API both for AOT and WASM. +*/ + +#define loader_malloc(size, error_buf, error_buf_size) \ + runtime_malloc(size, NULL, error_buf, error_buf_size) +static void +set_error_buf_v(const WASMModuleCommon *module, char *error_buf, + uint32 error_buf_size, const char *format, ...) +{ + va_list args; + char buf[128]; + if (error_buf != NULL) { + va_start(args, format); + vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + if (module->module_type == Wasm_Module_AoT) { + snprintf(error_buf, error_buf_size, "AOT module load failed: %s", + buf); + } + else if (module->module_type == Wasm_Module_Bytecode) { + snprintf(error_buf, error_buf_size, "WASM module load failed: %s", + buf); + } + } +} +#endif + #if WASM_ENABLE_FAST_JIT != 0 static JitCompOptions jit_options = { 0 }; #endif @@ -1198,27 +1228,34 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf, if (get_package_type(buf, size) == Wasm_Module_Bytecode) { #if WASM_ENABLE_INTERP != 0 module_common = - (WASMModuleCommon *)wasm_load(buf, size, error_buf, error_buf_size); - return register_module_with_null_name(module_common, error_buf, - error_buf_size); + (WASMModuleCommon *)wasm_load(buf, size, +#if WASM_ENABLE_MULTI_MODULE != 0 + true, +#endif + error_buf, error_buf_size); #endif } else if (get_package_type(buf, size) == Wasm_Module_AoT) { #if WASM_ENABLE_AOT != 0 module_common = (WASMModuleCommon *)aot_load_from_aot_file( buf, size, error_buf, error_buf_size); - return register_module_with_null_name(module_common, error_buf, - error_buf_size); #endif } - - if (size < 4) - set_error_buf(error_buf, error_buf_size, - "WASM module load failed: unexpected end"); - else - set_error_buf(error_buf, error_buf_size, - "WASM module load failed: magic header not detected"); - return NULL; + else { + if (size < 4) + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: unexpected end"); + else + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: magic header not detected"); + return NULL; + } + if (!module_common) { + LOG_DEBUG("WASM module load failed"); + return NULL; + } + return register_module_with_null_name(module_common, error_buf, + error_buf_size); } WASMModuleCommon * @@ -1231,6 +1268,10 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot, #if WASM_ENABLE_INTERP != 0 module_common = (WASMModuleCommon *)wasm_load_from_sections( section_list, error_buf, error_buf_size); + if (!module_common) { + LOG_DEBUG("WASM module load failed from sections"); + return NULL; + } return register_module_with_null_name(module_common, error_buf, error_buf_size); #endif @@ -1239,6 +1280,10 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot, #if WASM_ENABLE_AOT != 0 module_common = (WASMModuleCommon *)aot_load_from_sections( section_list, error_buf, error_buf_size); + if (!module_common) { + LOG_DEBUG("WASM module load failed from sections"); + return NULL; + } return register_module_with_null_name(module_common, error_buf, error_buf_size); #endif @@ -5663,6 +5708,314 @@ wasm_runtime_is_import_global_linked(const char *module_name, #endif } +#if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0 +WASMExport * +loader_find_export(const WASMModuleCommon *module, const char *module_name, + const char *field_name, uint8 export_kind, char *error_buf, + uint32 error_buf_size) +{ + WASMExport *exports = NULL, *result = NULL, *export; + uint32 export_count = 0, i; +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + AOTModule *aot_module = (AOTModule *)module; + exports = (WASMExport *)aot_module->exports; + export_count = aot_module->export_count; + } +#endif +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + WASMModule *wasm_module = (WASMModule *)module; + exports = wasm_module->exports; + export_count = wasm_module->export_count; + } +#endif + for (i = 0, export = exports; i < export_count; ++i, ++export) { + if (export->kind == export_kind && !strcmp(field_name, export->name)) { + result = export; + goto exit; + } + } + if (i == export_count) { + LOG_DEBUG("can not find an export %d named %s in the module %s", + export_kind, field_name, module_name); + set_error_buf(error_buf, error_buf_size, + "unknown import or incompatible import type"); + } +exit: + return result; +} +#endif + +#if WASM_ENABLE_MULTI_MODULE != 0 +WASMModuleCommon * +wasm_runtime_search_sub_module(const WASMModuleCommon *parent_module, + const char *sub_module_name) +{ + WASMRegisteredModule *node = NULL; +#if WASM_ENABLE_AOT != 0 + if (parent_module->module_type == Wasm_Module_AoT) { + node = bh_list_first_elem( + ((AOTModule *)parent_module)->import_module_list); + } +#endif +#if WASM_ENABLE_INTERP != 0 + if (parent_module->module_type == Wasm_Module_Bytecode) { + node = bh_list_first_elem( + ((WASMModule *)parent_module)->import_module_list); + } +#endif + while (node && strcmp(sub_module_name, node->module_name)) { + node = bh_list_elem_next(node); + } + return node ? node->module : NULL; +} + +bool +wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module, + const char *sub_module_name, + WASMModuleCommon *sub_module) +{ + /* register sub_module into its parent sub module list */ + WASMRegisteredModule *node = NULL; + bh_list_status ret; + + if (wasm_runtime_search_sub_module(parent_module, sub_module_name)) { + LOG_DEBUG("%s has been registered in its parent", sub_module_name); + return true; + } + + node = loader_malloc(sizeof(WASMRegisteredModule), NULL, 0); + if (!node) { + return false; + } + + node->module_name = sub_module_name; + node->module = sub_module; +#if WASM_ENABLE_AOT != 0 + if (parent_module->module_type == Wasm_Module_AoT) { + ret = bh_list_insert(((AOTModule *)parent_module)->import_module_list, + node); + } +#endif +#if WASM_ENABLE_INTERP != 0 + if (parent_module->module_type == Wasm_Module_Bytecode) { + ret = bh_list_insert(((WASMModule *)parent_module)->import_module_list, + node); + } +#endif + bh_assert(BH_LIST_SUCCESS == ret); + (void)ret; + return true; +} + +WASMModuleCommon * +wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module, + const char *sub_module_name, char *error_buf, + uint32 error_buf_size) +{ + WASMModuleCommon *sub_module = NULL; + bool ret = false; + uint8 *buffer = NULL; + uint32 buffer_size = 0; + + /* check the registered module list of the parent */ + sub_module = wasm_runtime_search_sub_module(parent_module, sub_module_name); + if (sub_module) { + LOG_DEBUG("%s has been loaded before", sub_module_name); + return sub_module; + } + + /* check the global registered module list */ + sub_module = wasm_runtime_find_module_registered(sub_module_name); + if (sub_module) { + LOG_DEBUG("%s has been loaded", sub_module_name); + goto wasm_runtime_register_sub_module; + } + LOG_VERBOSE("loading %s", sub_module_name); + if (!reader) { + set_error_buf_v(parent_module, error_buf, error_buf_size, + "no sub module reader to load %s", sub_module_name); + return NULL; + } + /* start to maintain a loading module list */ + ret = wasm_runtime_is_loading_module(sub_module_name); + if (ret) { + set_error_buf_v(parent_module, error_buf, error_buf_size, + "found circular dependency on %s", sub_module_name); + return NULL; + } + ret = wasm_runtime_add_loading_module(sub_module_name, error_buf, + error_buf_size); + if (!ret) { + LOG_DEBUG("can not add %s into loading module list\n", sub_module_name); + return NULL; + } + + ret = reader(parent_module->module_type, sub_module_name, &buffer, + &buffer_size); + if (!ret) { + LOG_DEBUG("read the file of %s failed", sub_module_name); + set_error_buf_v(parent_module, error_buf, error_buf_size, + "unknown import", sub_module_name); + goto delete_loading_module; + } + if (get_package_type(buffer, buffer_size) != parent_module->module_type) { + LOG_DEBUG("moudle %s type error", sub_module_name); + goto delete_loading_module; + } + if (get_package_type(buffer, buffer_size) == Wasm_Module_Bytecode) { +#if WASM_ENABLE_INTERP != 0 + sub_module = (WASMModuleCommon *)wasm_load(buffer, buffer_size, false, + error_buf, error_buf_size); +#endif + } + else if (get_package_type(buffer, buffer_size) == Wasm_Module_AoT) { +#if WASM_ENABLE_AOT != 0 + sub_module = (WASMModuleCommon *)aot_load_from_aot_file( + buffer, buffer_size, error_buf, error_buf_size); +#endif + } + if (!sub_module) { + LOG_DEBUG("error: can not load the sub_module %s", sub_module_name); + /* others will be destroyed in runtime_destroy() */ + goto destroy_file_buffer; + } + wasm_runtime_delete_loading_module(sub_module_name); + /* register on a global list */ + ret = wasm_runtime_register_module_internal( + sub_module_name, (WASMModuleCommon *)sub_module, buffer, buffer_size, + error_buf, error_buf_size); + if (!ret) { + LOG_DEBUG("error: can not register module %s globally\n", + sub_module_name); + /* others will be unloaded in runtime_destroy() */ + goto unload_module; + } + + /* register into its parent list */ +wasm_runtime_register_sub_module: + ret = wasm_runtime_register_sub_module(parent_module, sub_module_name, + sub_module); + if (!ret) { + set_error_buf_v(parent_module, error_buf, error_buf_size, + "failed to register sub module %s", sub_module_name); + /* since it is in the global module list, no need to + * unload the module. the runtime_destroy() will do it + */ + return NULL; + } + + return sub_module; + +unload_module: + wasm_runtime_unload(sub_module); + +destroy_file_buffer: + if (destroyer) { + destroyer(buffer, buffer_size); + } + else { + LOG_WARNING("need to release the reading buffer of %s manually", + sub_module_name); + } + +delete_loading_module: + wasm_runtime_delete_loading_module(sub_module_name); + return NULL; +} + +bool +wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, + WASMModuleInstanceCommon *module_inst, + uint32 stack_size, uint32 heap_size, + char *error_buf, uint32 error_buf_size) +{ + bh_list *sub_module_inst_list = NULL; + WASMRegisteredModule *sub_module_list_node = NULL; + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) { + sub_module_inst_list = + ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e) + ->sub_module_inst_list; + sub_module_list_node = + bh_list_first_elem(((AOTModule *)module)->import_module_list); + } +#endif +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + sub_module_inst_list = + ((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e) + ->sub_module_inst_list; + sub_module_list_node = + bh_list_first_elem(((WASMModule *)module)->import_module_list); + } +#endif + while (sub_module_list_node) { + WASMSubModInstNode *sub_module_inst_list_node = NULL; + WASMModuleCommon *sub_module = sub_module_list_node->module; + WASMModuleInstanceCommon *sub_module_inst = NULL; + sub_module_inst = wasm_runtime_instantiate_internal( + sub_module, NULL, NULL, stack_size, heap_size, error_buf, + error_buf_size); + if (!sub_module_inst) { + LOG_DEBUG("instantiate %s failed", + sub_module_list_node->module_name); + return false; + } + sub_module_inst_list_node = loader_malloc(sizeof(WASMSubModInstNode), + error_buf, error_buf_size); + if (!sub_module_inst_list_node) { + LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d", + sizeof(WASMSubModInstNode)); + if (sub_module_inst) + wasm_runtime_deinstantiate_internal(sub_module_inst, false); + return false; + } + sub_module_inst_list_node->module_inst = + (WASMModuleInstance *)sub_module_inst; + sub_module_inst_list_node->module_name = + sub_module_list_node->module_name; + bh_list_status ret = + bh_list_insert(sub_module_inst_list, sub_module_inst_list_node); + bh_assert(BH_LIST_SUCCESS == ret); + (void)ret; + sub_module_list_node = bh_list_elem_next(sub_module_list_node); + } + + return true; +} + +void +wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst) +{ + bh_list *list = NULL; +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + list = ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e) + ->sub_module_inst_list; + } +#endif +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + list = + ((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e) + ->sub_module_inst_list; + } +#endif + + WASMSubModInstNode *node = bh_list_first_elem(list); + while (node) { + WASMSubModInstNode *next_node = bh_list_elem_next(node); + bh_list_remove(list, node); + wasm_runtime_deinstantiate_internal( + (WASMModuleInstanceCommon *)node->module_inst, false); + wasm_runtime_free(node); + node = next_node; + } +} +#endif /* end of WASM_ENABLE_MULTI_MODULE */ #if WASM_ENABLE_MODULE_INST_CONTEXT != 0 void * wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst, diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 19d0af117..a834d67f2 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -788,6 +788,9 @@ wasm_runtime_register_module_internal(const char *module_name, void wasm_runtime_unregister_module(const WASMModuleCommon *module); +WASMModuleCommon * +wasm_runtime_find_module_registered(const char *module_name); + bool wasm_runtime_add_loading_module(const char *module_name, char *error_buf, uint32 error_buf_size); @@ -800,6 +803,35 @@ wasm_runtime_is_loading_module(const char *module_name); void wasm_runtime_destroy_loading_module_list(); + +WASMModuleCommon * +wasm_runtime_search_sub_module(const WASMModuleCommon *parent_module, + const char *sub_module_name); + +bool +wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module, + const char *sub_module_name, + WASMModuleCommon *sub_module); + +WASMModuleCommon * +wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module, + const char *sub_module_name, char *error_buf, + uint32 error_buf_size); + +bool +wasm_runtime_sub_module_instantiate(WASMModuleCommon *module, + WASMModuleInstanceCommon *module_inst, + uint32 stack_size, uint32 heap_size, + char *error_buf, uint32 error_buf_size); +void +wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst); +#endif + +#if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0 +WASMExport * +loader_find_export(const WASMModuleCommon *module, const char *module_name, + const char *field_name, uint8 export_kind, char *error_buf, + uint32 error_buf_size); #endif /* WASM_ENALBE_MULTI_MODULE */ bool diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 48ed55933..2a30ddc93 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -311,7 +311,7 @@ wasm_runtime_is_xip_file(const uint8_t *buf, uint32_t size); /** * Callback to load a module file into a buffer in multi-module feature */ -typedef bool (*module_reader)(const char *module_name, +typedef bool (*module_reader)(package_type_t module_type,const char *module_name, uint8_t **p_buffer, uint32_t *p_size); /** diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 130ad4392..cf8b7719c 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -694,34 +694,10 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name, const char *field_name, uint8 export_kind, char *error_buf, uint32 error_buf_size) { - WASMExport *export; - uint32 i; - - for (i = 0, export = module->exports; i < module->export_count; - ++i, ++export) { - /** - * need to consider a scenario that different kinds of exports - * may have the same name, like - * (table (export "m1" "exported") 10 funcref) - * (memory (export "m1" "exported") 10) - **/ - if (export->kind == export_kind && !strcmp(field_name, export->name)) { - break; - } - } - - if (i == module->export_count) { - LOG_DEBUG("can not find an export %d named %s in the module %s", - export_kind, field_name, module_name); - set_error_buf(error_buf, error_buf_size, - "unknown import or incompatible import type"); - return NULL; - } - - (void)module_name; - - /* since there is a validation in load_export_section(), it is for sure - * export->index is valid*/ + WASMExport *export = + loader_find_export((WASMModuleCommon *)module, module_name, field_name, + export_kind, error_buf, error_buf_size); + ; return export; } #endif @@ -912,152 +888,6 @@ wasm_loader_resolve_global(const char *module_name, const char *global_name, return global; } -static WASMModule * -search_sub_module(const WASMModule *parent_module, const char *sub_module_name) -{ - WASMRegisteredModule *node = - bh_list_first_elem(parent_module->import_module_list); - while (node && strcmp(sub_module_name, node->module_name)) { - node = bh_list_elem_next(node); - } - return node ? (WASMModule *)node->module : NULL; -} - -static bool -register_sub_module(const WASMModule *parent_module, - const char *sub_module_name, WASMModule *sub_module) -{ - /* register sub_module into its parent sub module list */ - WASMRegisteredModule *node = NULL; - bh_list_status ret; - - if (search_sub_module(parent_module, sub_module_name)) { - LOG_DEBUG("%s has been registered in its parent", sub_module_name); - return true; - } - - node = loader_malloc(sizeof(WASMRegisteredModule), NULL, 0); - if (!node) { - return false; - } - - node->module_name = sub_module_name; - node->module = (WASMModuleCommon *)sub_module; - ret = bh_list_insert(parent_module->import_module_list, node); - bh_assert(BH_LIST_SUCCESS == ret); - (void)ret; - return true; -} - -static WASMModule * -load_depended_module(const WASMModule *parent_module, - const char *sub_module_name, char *error_buf, - uint32 error_buf_size) -{ - WASMModule *sub_module = NULL; - bool ret = false; - uint8 *buffer = NULL; - uint32 buffer_size = 0; - const module_reader reader = wasm_runtime_get_module_reader(); - const module_destroyer destroyer = wasm_runtime_get_module_destroyer(); - - /* check the registered module list of the parent */ - sub_module = search_sub_module(parent_module, sub_module_name); - if (sub_module) { - LOG_DEBUG("%s has been loaded before", sub_module_name); - return sub_module; - } - - /* check the global registered module list */ - sub_module = - (WASMModule *)wasm_runtime_find_module_registered(sub_module_name); - if (sub_module) { - LOG_DEBUG("%s has been loaded", sub_module_name); - goto register_sub_module; - } - - LOG_VERBOSE("loading %s", sub_module_name); - - if (!reader) { - set_error_buf_v(error_buf, error_buf_size, - "no sub module reader to load %s", sub_module_name); - return NULL; - } - - /* start to maintain a loading module list */ - ret = wasm_runtime_is_loading_module(sub_module_name); - if (ret) { - set_error_buf_v(error_buf, error_buf_size, - "found circular dependency on %s", sub_module_name); - return NULL; - } - - ret = wasm_runtime_add_loading_module(sub_module_name, error_buf, - error_buf_size); - if (!ret) { - LOG_DEBUG("can not add %s into loading module list\n", sub_module_name); - return NULL; - } - - ret = reader(sub_module_name, &buffer, &buffer_size); - if (!ret) { - LOG_DEBUG("read the file of %s failed", sub_module_name); - set_error_buf_v(error_buf, error_buf_size, "unknown import", - sub_module_name); - goto delete_loading_module; - } - - sub_module = - wasm_loader_load(buffer, buffer_size, false, error_buf, error_buf_size); - if (!sub_module) { - LOG_DEBUG("error: can not load the sub_module %s", sub_module_name); - /* others will be destroyed in runtime_destroy() */ - goto destroy_file_buffer; - } - - wasm_runtime_delete_loading_module(sub_module_name); - - /* register on a global list */ - ret = wasm_runtime_register_module_internal( - sub_module_name, (WASMModuleCommon *)sub_module, buffer, buffer_size, - error_buf, error_buf_size); - if (!ret) { - LOG_DEBUG("error: can not register module %s globally\n", - sub_module_name); - /* others will be unloaded in runtime_destroy() */ - goto unload_module; - } - - /* register into its parent list */ -register_sub_module: - ret = register_sub_module(parent_module, sub_module_name, sub_module); - if (!ret) { - set_error_buf_v(error_buf, error_buf_size, - "failed to register sub module %s", sub_module_name); - /* since it is in the global module list, no need to - * unload the module. the runtime_destroy() will do it - */ - return NULL; - } - - return sub_module; - -unload_module: - wasm_loader_unload(sub_module); - -destroy_file_buffer: - if (destroyer) { - destroyer(buffer, buffer_size); - } - else { - LOG_WARNING("need to release the reading buffer of %s manually", - sub_module_name); - } - -delete_loading_module: - wasm_runtime_delete_loading_module(sub_module_name); - return NULL; -} #endif /* end of WASM_ENABLE_MULTI_MODULE */ static bool @@ -1104,8 +934,9 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end, #if WASM_ENABLE_MULTI_MODULE != 0 else { if (!wasm_runtime_is_built_in_module(sub_module_name)) { - sub_module = load_depended_module(parent_module, sub_module_name, - error_buf, error_buf_size); + sub_module = (WASMModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)parent_module, sub_module_name, error_buf, + error_buf_size); if (!sub_module) { return false; } @@ -1193,8 +1024,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #if WASM_ENABLE_MULTI_MODULE != 0 if (!wasm_runtime_is_built_in_module(sub_module_name)) { - sub_module = load_depended_module(parent_module, sub_module_name, - error_buf, error_buf_size); + sub_module = (WASMModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)parent_module, sub_module_name, error_buf, + error_buf_size); if (!sub_module) { return false; } @@ -1327,8 +1159,9 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end, #if WASM_ENABLE_MULTI_MODULE != 0 if (!wasm_runtime_is_built_in_module(sub_module_name)) { - sub_module = load_depended_module(parent_module, sub_module_name, - error_buf, error_buf_size); + sub_module = (WASMModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)parent_module, sub_module_name, error_buf, + error_buf_size); if (!sub_module) { return false; } @@ -1427,8 +1260,9 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, #if WASM_ENABLE_MULTI_MODULE != 0 if (!global->is_linked && !wasm_runtime_is_built_in_module(sub_module_name)) { - sub_module = load_depended_module(parent_module, sub_module_name, - error_buf, error_buf_size); + sub_module = (WASMModule *)wasm_runtime_load_depended_module( + (WASMModuleCommon *)parent_module, sub_module_name, error_buf, + error_buf_size); if (!sub_module) { return false; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 301038a4d..af2a61c88 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -51,11 +51,15 @@ set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...) } WASMModule * -wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size) +wasm_load(uint8 *buf, uint32 size, +#if WASM_ENABLE_MULTI_MODULE != 0 + bool main_module, +#endif + char *error_buf, uint32 error_buf_size) { return wasm_loader_load(buf, size, #if WASM_ENABLE_MULTI_MODULE != 0 - true, + main_module, #endif error_buf, error_buf_size); } @@ -1265,78 +1269,6 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, return ret; } -#if WASM_ENABLE_MULTI_MODULE != 0 -static bool -sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst, - uint32 stack_size, uint32 heap_size, char *error_buf, - uint32 error_buf_size) -{ - bh_list *sub_module_inst_list = module_inst->e->sub_module_inst_list; - WASMRegisteredModule *sub_module_list_node = - bh_list_first_elem(module->import_module_list); - - while (sub_module_list_node) { - WASMSubModInstNode *sub_module_inst_list_node = NULL; - WASMModule *sub_module = (WASMModule *)sub_module_list_node->module; - WASMModuleInstance *sub_module_inst = NULL; - - sub_module_inst = - wasm_instantiate(sub_module, NULL, NULL, stack_size, heap_size, - error_buf, error_buf_size); - if (!sub_module_inst) { - LOG_DEBUG("instantiate %s failed", - sub_module_list_node->module_name); - goto failed; - } - - sub_module_inst_list_node = runtime_malloc(sizeof(WASMSubModInstNode), - error_buf, error_buf_size); - if (!sub_module_inst_list_node) { - LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d", - sizeof(WASMSubModInstNode)); - goto failed; - } - - sub_module_inst_list_node->module_inst = sub_module_inst; - sub_module_inst_list_node->module_name = - sub_module_list_node->module_name; - bh_list_status ret = - bh_list_insert(sub_module_inst_list, sub_module_inst_list_node); - bh_assert(BH_LIST_SUCCESS == ret); - (void)ret; - - sub_module_list_node = bh_list_elem_next(sub_module_list_node); - - continue; - failed: - if (sub_module_inst_list_node) { - bh_list_remove(sub_module_inst_list, sub_module_inst_list_node); - wasm_runtime_free(sub_module_inst_list_node); - } - - if (sub_module_inst) - wasm_deinstantiate(sub_module_inst, false); - return false; - } - - return true; -} - -static void -sub_module_deinstantiate(WASMModuleInstance *module_inst) -{ - bh_list *list = module_inst->e->sub_module_inst_list; - WASMSubModInstNode *node = bh_list_first_elem(list); - while (node) { - WASMSubModInstNode *next_node = bh_list_elem_next(node); - bh_list_remove(list, node); - wasm_deinstantiate(node->module_inst, false); - wasm_runtime_free(node); - node = next_node; - } -} -#endif - static bool check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, uint32 error_buf_size) @@ -1713,8 +1645,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, #if WASM_ENABLE_MULTI_MODULE != 0 module_inst->e->sub_module_inst_list = &module_inst->e->sub_module_inst_list_head; - ret = sub_module_instantiate(module, module_inst, stack_size, heap_size, - error_buf, error_buf_size); + ret = wasm_runtime_sub_module_instantiate( + (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst, + stack_size, heap_size, error_buf, error_buf_size); if (!ret) { LOG_DEBUG("build a sub module list failed"); goto fail; @@ -2197,7 +2130,8 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) #endif #if WASM_ENABLE_MULTI_MODULE != 0 - sub_module_deinstantiate(module_inst); + wasm_runtime_sub_module_deinstantiate( + (WASMModuleInstanceCommon *)module_inst); #endif if (module_inst->memory_count > 0) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 605cefc6c..d6661fa0f 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -396,7 +396,11 @@ wasm_get_func_code_end(WASMFunctionInstance *func) } WASMModule * -wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size); +wasm_load(uint8 *buf, uint32 size, +#if WASM_ENABLE_MULTI_MODULE != 0 + bool main_module, +#endif + char *error_buf, uint32 error_buf_size); WASMModule * wasm_load_from_sections(WASMSection *section_list, char *error_buf, diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 45237a215..0051e628c 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -420,19 +420,28 @@ handle_module_path(const char *module_path) static char *module_search_path = "."; static bool -module_reader_callback(const char *module_name, uint8 **p_buffer, - uint32 *p_size) +module_reader_callback(package_type_t module_type, const char *module_name, + uint8 **p_buffer, uint32 *p_size) { - const char *format = "%s/%s.wasm"; + char *file_format; +#if WASM_ENABLE_INTERP != 0 + if (module_type == Wasm_Module_Bytecode) + file_format = ".wasm"; +#endif +#if WASM_ENABLE_AOT != 0 + if (module_type == Wasm_Module_AoT) + file_format = ".aot"; + +#endif + const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) - + strlen(".wasm") + 1; + + strlen(file_format) + 1; char *wasm_file_name = BH_MALLOC(sz); if (!wasm_file_name) { return false; } - - snprintf(wasm_file_name, sz, format, module_search_path, module_name); - + snprintf(wasm_file_name, sz, format, module_search_path, module_name, + file_format); *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size); wasm_runtime_free(wasm_file_name); diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 8b1b1f371..121be4195 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -204,20 +204,29 @@ handle_module_path(const char *module_path) static char *module_search_path = "."; static bool -module_reader_callback(const char *module_name, uint8 **p_buffer, - uint32 *p_size) +module_reader_callback(package_type_t module_type, const char *module_name, + uint8 **p_buffer, uint32 *p_size) { - const char *format = "%s/%s.wasm"; - uint32 sz = (uint32)(strlen(module_search_path) + strlen("/") - + strlen(module_name) + strlen(".wasm") + 1); + char *file_format; +#if WASM_ENABLE_INTERP != 0 + if (module_type == Wasm_Module_Bytecode) + file_format = ".wasm"; +#endif +#if WASM_ENABLE_AOT != 0 + if (module_type == Wasm_Module_AoT) + file_format = ".aot"; + +#endif + const char *format = "%s/%s%s"; + int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + + strlen(file_format) + 1; char *wasm_file_name = BH_MALLOC(sz); if (!wasm_file_name) { return false; } - - snprintf(wasm_file_name, sz, format, module_search_path, module_name); - - *p_buffer = (uint8 *)bh_read_file_to_buffer(wasm_file_name, p_size); + snprintf(wasm_file_name, sz, format, module_search_path, module_name, + file_format); + *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size); wasm_runtime_free(wasm_file_name); return *p_buffer != NULL; diff --git a/samples/multi-module/CMakeLists.txt b/samples/multi-module/CMakeLists.txt index 2769b9779..ee6c98df4 100644 --- a/samples/multi-module/CMakeLists.txt +++ b/samples/multi-module/CMakeLists.txt @@ -43,8 +43,12 @@ if (NOT CMAKE_BUILD_TYPE) endif () set(WAMR_BUILD_INTERP 1) -set(WAMR_BUILD_AOT 0) -set(WAMR_BUILD_JIT 0) +if (NOT DEFINED WAMR_BUILD_AOT) + set(WAMR_BUILD_AOT 0) +endif () +if (NOT DEFINED WAMR_BUILD_JIT) + set(WAMR_BUILD_JIT 0) +endif () set(WAMR_BUILD_LIBC_BUILTIN 1) set(WAMR_BUILD_LIBC_WASI 1) set(WAMR_BUILD_MULTI_MODULE 1) @@ -144,6 +148,43 @@ ExternalProject_Add(WASM_MODULE ./mE.wasm ${CMAKE_BINARY_DIR} ) +################ WASM MODULES TO AOT +if (WAMR_BUILD_AOT EQUAL 1) + set(WAMR_COMPILER_DIR ${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build) + message(CHECK_START "Detecting WAMR_COMPILER at ${WAMR_COMPILER_DIR}") + find_file(WAMR_COMPILER + wamrc + PATHS "${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build" + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + if(WAMR_COMPILER) + message(CHECK_PASS "found") + else() + message(CHECK_FAIL "not found") + endif() + if((NOT EXISTS ${WAMR_COMPILER}) ) + message(FATAL_ERROR "Please build wamrc under the path=${WAMR_ROOT_DIR}/wamr-compiler/ ") + else() + message(STATUS "WAMR_COMPILER is ${WAMR_COMPILER}") + endif() + + add_custom_target( + wasm_to_aot + ALL + DEPENDS + WASM_MODULE ${WAMR_COMPILER} + COMMAND + ${WAMR_COMPILER} -o mA.aot ./mA.wasm + COMMAND + ${WAMR_COMPILER} -o mB.aot ./mB.wasm + COMMAND + ${WAMR_COMPILER} -o mC.aot ./mC.wasm + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} + ) +endif() + ################ NATIVE include_directories(${CMAKE_CURRENT_LIST_DIR}/src) include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) diff --git a/samples/multi-module/README.md b/samples/multi-module/README.md new file mode 100644 index 000000000..1ec92620c --- /dev/null +++ b/samples/multi-module/README.md @@ -0,0 +1,20 @@ +# WAMR MULTI-MODUEL SAMPLE +**WAMR supports *multi-module* in both *interpreter* mode and *aot* mode.** + +Multi-modules will determine the running mode based on the type of the main module. + + +``` shell +$ mkdir build +$ cd build +$ cmake .. +$ make +$ # It will build multi-module runtime and +$ # wasm file under the ./build . +$ # If you have built wamrc, +$ # aot file will also genrate. +$ ./multi-module mC.wasm +$ ... +$ ./multi-module mC.aot +$ ... + diff --git a/samples/multi-module/src/main.c b/samples/multi-module/src/main.c index ca95ded5f..361856136 100644 --- a/samples/multi-module/src/main.c +++ b/samples/multi-module/src/main.c @@ -1,59 +1,63 @@ #include #include #include - #include "bh_read_file.h" #include "platform_common.h" #include "wasm_export.h" -static char * -build_module_path(const char *module_name) +#if WASM_ENABLE_MULTI_MODULE != 0 +static char *module_search_path = "."; +static bool +module_reader_callback(package_type_t module_type, const char *module_name, + uint8 **p_buffer, uint32 *p_size) { - const char *module_search_path = "."; - const char *format = "%s/%s.wasm"; + char *file_format; +#if WASM_ENABLE_INTERP != 0 + if (module_type == Wasm_Module_Bytecode) + file_format = ".wasm"; +#endif +#if WASM_ENABLE_AOT != 0 + if (module_type == Wasm_Module_AoT) + file_format = ".aot"; + +#endif + const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) - + strlen(".wasm") + 1; + + strlen(file_format) + 1; char *wasm_file_name = BH_MALLOC(sz); if (!wasm_file_name) { - return NULL; - } - - snprintf(wasm_file_name, sz, format, module_search_path, module_name); - return wasm_file_name; -} - -static bool -module_reader_cb(const char *module_name, uint8 **p_buffer, uint32 *p_size) -{ - char *wasm_file_path = build_module_path(module_name); - if (!wasm_file_path) { return false; } + snprintf(wasm_file_name, sz, format, module_search_path, module_name, + file_format); + *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size); - printf("- bh_read_file_to_buffer %s\n", wasm_file_path); - *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_path, p_size); - BH_FREE(wasm_file_path); + wasm_runtime_free(wasm_file_name); return *p_buffer != NULL; } static void -module_destroyer_cb(uint8 *buffer, uint32 size) +moudle_destroyer(uint8 *buffer, uint32 size) { - printf("- release the read file buffer\n"); if (!buffer) { return; } - BH_FREE(buffer); + wasm_runtime_free(buffer); buffer = NULL; } +#endif /* WASM_ENABLE_MULTI_MODULE */ /* 10M */ static char sandbox_memory_space[10 * 1024 * 1024] = { 0 }; int -main() +main(int argc, char *argv[]) { bool ret = false; + if (argc != 2) { + return -1; + } + char *wasm_file = argv[1]; /* 16K */ const uint32 stack_size = 16 * 1024; const uint32 heap_size = 16 * 1024; @@ -84,16 +88,16 @@ main() #if WASM_ENABLE_MULTI_MODULE != 0 printf("- wasm_runtime_set_module_reader\n"); /* set module reader and destroyer */ - wasm_runtime_set_module_reader(module_reader_cb, module_destroyer_cb); + wasm_runtime_set_module_reader(module_reader_callback, moudle_destroyer); #endif /* load WASM byte buffer from WASM bin file */ - if (!module_reader_cb("mC", &file_buf, &file_buf_size)) { + if (!(file_buf = + (uint8 *)bh_read_file_to_buffer(wasm_file, &file_buf_size))) goto RELEASE_RUNTIME; - } - /* load mC and let WAMR load mA and mB */ printf("- wasm_runtime_load\n"); + if (!(module = wasm_runtime_load(file_buf, file_buf_size, error_buf, sizeof(error_buf)))) { printf("%s\n", error_buf); @@ -158,7 +162,7 @@ UNLOAD_MODULE: printf("- wasm_runtime_unload\n"); wasm_runtime_unload(module); RELEASE_BINARY: - module_destroyer_cb(file_buf, file_buf_size); + moudle_destroyer(file_buf, file_buf_size); RELEASE_RUNTIME: printf("- wasm_runtime_destroy\n"); wasm_runtime_destroy(); diff --git a/tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch b/tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch new file mode 100644 index 000000000..4494e0856 --- /dev/null +++ b/tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch @@ -0,0 +1,174 @@ +diff --git a/test/core/linking.wast b/test/core/linking.wast +index d0bfb5f..6617945 100644 +--- a/test/core/linking.wast ++++ b/test/core/linking.wast +@@ -35,7 +35,7 @@ + + + ;; Globals +- ++(; + (module $Mg + (global $glob (export "glob") i32 (i32.const 42)) + (func (export "get") (result i32) (global.get $glob)) +@@ -63,7 +63,7 @@ + (export "Mg.get_mut" (func $get_mut)) + (export "Mg.set_mut" (func $set_mut)) + ) +- ++;) + (; + (assert_return (get $Mg "glob") (i32.const 42)) + (assert_return (get $Ng "Mg.glob") (i32.const 42)) +@@ -84,7 +84,7 @@ + (assert_return (invoke $Ng "Mg.get_mut") (i32.const 241)) + ;) + +- ++(; + (assert_unlinkable + (module (import "Mg" "mut_glob" (global i32))) + "incompatible import type" +@@ -166,7 +166,7 @@ + (call_indirect (type 1) (local.get 0)) + ) + ) +- ++;) + (; + (assert_return (invoke $Mt "call" (i32.const 2)) (i32.const 4)) + (assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const 4)) +@@ -191,7 +191,7 @@ + (assert_return (invoke $Nt "call" (i32.const 3)) (i32.const -4)) + (assert_trap (invoke $Nt "call" (i32.const 4)) "indirect call type mismatch") + ;) +- ++(; + (module $Ot + (type (func (result i32))) + +@@ -204,7 +204,7 @@ + (call_indirect (type 0) (local.get 0)) + ) + ) +- ++;) + (; + (assert_return (invoke $Mt "call" (i32.const 3)) (i32.const 4)) + (assert_return (invoke $Nt "Mt.call" (i32.const 3)) (i32.const 4)) +@@ -231,7 +231,7 @@ + + (assert_trap (invoke $Ot "call" (i32.const 20)) "undefined element") + ;) +- ++(; + (module + (table (import "Mt" "tab") 0 funcref) + (elem (i32.const 9) $f) +@@ -266,7 +266,7 @@ + "unknown import" + ) + (assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized element") +- ++;) + ;; Unlike in the v1 spec, active element segments stored before an + ;; out-of-bounds access persist after the instantiation failure. + (; +@@ -297,7 +297,7 @@ + (assert_return (invoke $Mt "call" (i32.const 7)) (i32.const 0)) + ;) + +- ++(; + (module $Mtable_ex + (table $t1 (export "t-func") 1 funcref) + (table $t2 (export "t-extern") 1 externref) +@@ -308,7 +308,7 @@ + (table (import "Mtable_ex" "t-func") 1 funcref) + (table (import "Mtable_ex" "t-extern") 1 externref) + ) +- ++;) + (; + (assert_unlinkable + (module (table (import "Mtable_ex" "t-func") 1 externref)) +@@ -322,7 +322,7 @@ + + + ;; Memories +- ++(; + (module $Mm + (memory (export "mem") 1 5) + (data (i32.const 10) "\00\01\02\03\04\05\06\07\08\09") +@@ -357,14 +357,14 @@ + (i32.load8_u (local.get 0)) + ) + ) +- ++;) + (; + (assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 0xa7)) + (assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 0xa7)) + (assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2)) + (assert_return (invoke $Om "load" (i32.const 12)) (i32.const 0xa7)) + ;) +- ++(; + (module + (memory (import "Mm" "mem") 0) + (data (i32.const 0xffff) "a") +@@ -385,7 +385,7 @@ + (memory.grow (local.get 0)) + ) + ) +- ++;) + (; + (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 1)) + (assert_return (invoke $Pm "grow" (i32.const 2)) (i32.const 1)) +@@ -396,7 +396,7 @@ + (assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const -1)) + (assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5)) + ;) +- ++(; + (assert_unlinkable + (module + (func $host (import "spectest" "print")) +@@ -419,11 +419,12 @@ + ) + "out of bounds memory access" + ) ++;) + (; + (assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97)) + (assert_return (invoke $Mm "load" (i32.const 327670)) (i32.const 0)) + ;) +- ++(; + (assert_trap + (module + (memory (import "Mm" "mem") 1) +@@ -434,10 +435,11 @@ + ) + "out of bounds table access" + ) ++;) + (; + (assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 97)) + ;) +- ++(; + ;; Store is modified if the start function traps. + (module $Ms + (type $t (func (result i32))) +@@ -451,7 +453,7 @@ + ) + ) + (register "Ms" $Ms) +- ++;) + (; + (assert_trap + (module diff --git a/tests/wamr-test-suites/spec-test-script/runtest.py b/tests/wamr-test-suites/spec-test-script/runtest.py index a1e505bd0..633a57313 100755 --- a/tests/wamr-test-suites/spec-test-script/runtest.py +++ b/tests/wamr-test-suites/spec-test-script/runtest.py @@ -1299,6 +1299,16 @@ if __name__ == "__main__": # add new_module copied from the old into temp_file_repo[] temp_file_repo.append(new_module) + + if test_aot: + new_module_aot = os.path.join(tempfile.gettempdir(), name_new + ".aot") + r = compile_wasm_to_aot(new_module, new_module_aot, True, opts, r) + try: + assert_prompt(r, ['Compile success'], opts.start_timeout, True) + except: + raise Exception("compile wasm to aot failed") + # add aot module into temp_file_repo[] + temp_file_repo.append(new_module_aot) else: # there is no name defined in register cmd raise Exception("can not find module name from the register") @@ -1341,3 +1351,4 @@ if __name__ == "__main__": log("Leaving tempfiles: %s" % ([wast_tempfile, wasm_tempfile])) sys.exit(ret_code) + \ No newline at end of file diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 11650651c..1caaa89b0 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -333,6 +333,9 @@ function spec_test() if [[ ${ENABLE_SIMD} == 1 ]]; then git apply ../../spec-test-script/simd_ignore_cases.patch fi + if [[ ${ENABLE_MULTI_MODULE} == 1 && $1 == 'aot' ]]; then + git apply ../../spec-test-script/muti_module_aot_ignore_cases.patch + fi # udpate thread cases if [ ${ENABLE_MULTI_THREAD} == 1 ]; then @@ -424,7 +427,7 @@ function spec_test() # multi-module only enable in interp mode if [[ 1 == ${ENABLE_MULTI_MODULE} ]]; then - if [[ $1 == 'classic-interp' || $1 == 'fast-interp' ]]; then + if [[ $1 == 'classic-interp' || $1 == 'fast-interp' || $1 == 'aot' ]]; then ARGS_FOR_SPEC_TEST+="-M " fi fi @@ -897,4 +900,4 @@ fi echo -e "Test finish. Reports are under ${REPORT_DIR}" DEBUG set +xv pipefail echo "TEST SUCCESSFUL" -exit 0 +exit 0 \ No newline at end of file From cd0cec5bebff3dcca2d2900017bb0f386e488157 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Thu, 28 Sep 2023 09:15:56 +0800 Subject: [PATCH 43/58] Check ValueKind before extracting a constant int value (#2595) Only when the value kind is LLVMConstantIntValueKind and the value is not undef and not poison can we extract the value of a constant int. Fixes #2557 and #2559. --- core/iwasm/compilation/aot_compiler.h | 13 +++++++++++++ core/iwasm/compilation/aot_emit_control.c | 7 ++++--- core/iwasm/compilation/aot_emit_memory.c | 13 +++---------- core/iwasm/compilation/aot_emit_numberic.c | 10 +++++----- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index 40d79cf86..b6347c89d 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -363,6 +363,19 @@ check_type_compatible(uint8 src_type, uint8 dst_type) } \ } while (0) +/* if val is a constant integer and its value is not undef or poison */ +static inline bool +LLVMIsEfficientConstInt(LLVMValueRef val) +{ + return LLVMIsConstant(val) + && LLVMGetValueKind(val) == LLVMConstantIntValueKind + && !LLVMIsUndef(val) +#if LLVM_VERSION_NUMBER >= 12 + && !LLVMIsPoison(addr) +#endif + ; +} + bool aot_compile_wasm(AOTCompContext *comp_ctx); diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 75d1e622e..7e710f914 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -4,6 +4,7 @@ */ #include "aot_emit_control.h" +#include "aot_compiler.h" #include "aot_emit_exception.h" #include "../aot/aot_runtime.h" #include "../interpreter/wasm_loader.h" @@ -469,7 +470,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, p_frame_ip); } - if (!LLVMIsConstant(value)) { + if (!LLVMIsEfficientConstInt(value)) { /* Compare value is not constant, create condition br IR */ /* Create entry block */ format_block_name(name, sizeof(name), block->block_index, @@ -835,7 +836,7 @@ aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); } - if (!LLVMIsConstant(value_cmp)) { + if (!LLVMIsEfficientConstInt(value_cmp)) { /* Compare value is not constant, create condition br IR */ if (!(block_dst = get_target_block(func_ctx, br_depth))) { return false; @@ -972,7 +973,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); } - if (!LLVMIsConstant(value_cmp)) { + if (!LLVMIsEfficientConstInt(value_cmp)) { /* Compare value is not constant, create switch IR */ for (i = 0; i <= br_count; i++) { target_block = get_target_block(func_ctx, br_depths[i]); diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index c11989ebf..7484d4b5b 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -4,6 +4,7 @@ */ #include "aot_emit_memory.h" +#include "aot_compiler.h" #include "aot_emit_exception.h" #include "../aot/aot_runtime.h" #include "aot_intrinsic.h" @@ -145,11 +146,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, * have been thrown when converting float to integer before */ /* return addres directly if constant offset and inside memory space */ - if (LLVMIsConstant(addr) && !LLVMIsUndef(addr) -#if LLVM_VERSION_NUMBER >= 12 - && !LLVMIsPoison(addr) -#endif - ) { + if (LLVMIsEfficientConstInt(addr)) { uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset; uint32 num_bytes_per_page = @@ -911,11 +908,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, * have been thrown when converting float to integer before */ /* return addres directly if constant offset and inside memory space */ - if (!LLVMIsUndef(offset) && !LLVMIsUndef(bytes) -#if LLVM_VERSION_NUMBER >= 12 - && !LLVMIsPoison(offset) && !LLVMIsPoison(bytes) -#endif - && LLVMIsConstant(offset) && LLVMIsConstant(bytes)) { + if (LLVMIsEfficientConstInt(offset) && LLVMIsEfficientConstInt(bytes)) { uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(offset); uint64 mem_len = (uint64)LLVMConstIntGetZExtValue(bytes); uint32 num_bytes_per_page = diff --git a/core/iwasm/compilation/aot_emit_numberic.c b/core/iwasm/compilation/aot_emit_numberic.c index 4c63e8a40..f540dbe04 100644 --- a/core/iwasm/compilation/aot_emit_numberic.c +++ b/core/iwasm/compilation/aot_emit_numberic.c @@ -54,13 +54,13 @@ } while (0) #if LLVM_VERSION_NUMBER >= 12 -#define IS_CONST_ZERO(val) \ - (!LLVMIsUndef(val) && !LLVMIsPoison(val) && LLVMIsConstant(val) \ - && ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \ +#define IS_CONST_ZERO(val) \ + (LLVMIsEfficientConstInt(val) \ + && ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \ || (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0))) #else #define IS_CONST_ZERO(val) \ - (!LLVMIsUndef(val) && LLVMIsConstant(val) \ + (LLVMIsEfficientConstInt(val) \ && ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \ || (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0))) #endif @@ -473,7 +473,7 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip); } - if (LLVMIsConstant(right)) { + if (LLVMIsEfficientConstInt(right)) { int64 right_val = (int64)LLVMConstIntGetSExtValue(right); switch (right_val) { case 0: From ac6435884fb012863544a094d315c5886dca229a Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 28 Sep 2023 10:27:33 +0900 Subject: [PATCH 44/58] doc/memory_tune.md: "remove malloc" hack is not relevant to wasi-threads (#2603) --- doc/memory_tune.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/memory_tune.md b/doc/memory_tune.md index e14a1a164..05a1a633f 100644 --- a/doc/memory_tune.md +++ b/doc/memory_tune.md @@ -16,7 +16,7 @@ Note: - **linear memory**: a contiguous, mutable array of raw bytes. It is created with an initial size but might be grown dynamically. For most compilers, e.g. wasi-sdk, emsdk, rustc or asc, normally it includes three parts, data area, auxiliary stack area and heap area. For wasi-sdk, the initial/max size can be specified with `-Wl,--initial-memory=n1,--max-memory=n2`, for emsdk, the initial/max size can be specified with `-s INITIAL_MEMORY=n1 -s MAXIMUM_MEMORY=n2 -s ALLOW_MEMORY_GROWTH=1` or `-s TOTAL_MEMORY=n`, and for asc, they can be specified with `--initialMemory` and `--maximumMemory` flags. - If the memory access boundary check with hardware trap feature is enabled, e.g. in Linux/MacOS/Windows x86-64 by default, the linear memory is allocated by `os_mmap` from virtual address space instead of global heap. - **aux stack**: the auxiliary stack resides in linear memory to store some temporary data when calling wasm functions, for example, calling a wasm function with complex struct arguments. For wasi-sdk, the size can be specified with `-z stack-size=n`, for emsdk, the size can be specified with `-s TOTAL_STACK=n`. -- **app heap and libc heap**: the heap to allocate memory for wasm app, note that app heap is created only when the malloc/free functions (or __new/__release functions for AssemblyScript) are not exported and runtime can not detect the libc heap. To export the malloc/free functions, for wasi-sdk and emsdk, developer can use `-Wl,--export=malloc -Wl,--export=free` options, for asc, developer can use `--exportRuntime` option. For app heap, the size is specified by `wasm_runtime_instantiate`. It is recommended to export the malloc/free functions and disable app heap in single thread mode, and for multi-threading, as the libc heap isn't thread-safe, it is recommended to remove the dlmalloc.o from libc.a for wasi-sdk and use `-s MALLOC="none"` for emsdk, refer to [WAMR pthread library](./pthread_library.md) for more details. And developer can use `wasm_runtime_module_malloc/wasm_runtime_module_free` to allocate/free memory from/to app heap (or libc heap if malloc/free functions are exported). +- **app heap and libc heap**: the heap to allocate memory for wasm app, note that app heap is created only when the malloc/free functions (or __new/__release functions for AssemblyScript) are not exported and runtime can not detect the libc heap. To export the malloc/free functions, for wasi-sdk and emsdk, developer can use `-Wl,--export=malloc -Wl,--export=free` options, for asc, developer can use `--exportRuntime` option. For app heap, the size is specified by `wasm_runtime_instantiate`. It is recommended to export the malloc/free functions and disable app heap. However, if you are using [the old pthread implementation](./pthread_impls.md), you might need some workaround to avoid the libc heap as mentioned in [WAMR pthread library](./pthread_library.md). And developer can use `wasm_runtime_module_malloc/wasm_runtime_module_free` to allocate/free memory from/to app heap (or libc heap if malloc/free functions are exported). - **__data_end global and __heap_base global**: two globals exported by wasm application to indicate the end of data area and the base address of libc heap. For WAMR, it is recommended to export them as when there are no possible memory grow operations, runtime will truncate the linear memory into the size indicated by `__heap_base`, so as to reduce the footprint, or at least one page (64KB) is required by linear memory. ## Tune the memory usage From 3c17a36ccb09dfea1dc48a5a85ef17697d943b3e Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Thu, 28 Sep 2023 09:32:01 +0800 Subject: [PATCH 45/58] Patch implementations of vfbinop(min,max,pmin,pax) (#2584) According to the specification, - fNxM_pmin/max returns v1 or v2 based on flt(v1,v2) result - fNxM_min/max returns +/-NaN, +/-Inf, v1 or v2 based on more than flt(v1,v2) result Fixes issue #2561. --- .../compilation/simd/simd_floating_point.c | 249 ++++++++++++++---- 1 file changed, 204 insertions(+), 45 deletions(-) diff --git a/core/iwasm/compilation/simd/simd_floating_point.c b/core/iwasm/compilation/simd/simd_floating_point.c index d850fe8f7..7fcc1ab65 100644 --- a/core/iwasm/compilation/simd/simd_floating_point.c +++ b/core/iwasm/compilation/simd/simd_floating_point.c @@ -217,10 +217,9 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx, static bool simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, - FloatArithmetic arith_op, LLVMTypeRef vector_type) + FloatArithmetic op, LLVMTypeRef vector_type) { - LLVMValueRef lhs, rhs, result; - LLVMRealPredicate op = FLOAT_MIN == arith_op ? LLVMRealULT : LLVMRealUGT; + LLVMValueRef lhs, rhs, cmp, selected; if (!(rhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) @@ -229,80 +228,240 @@ simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - if (!(result = LLVMBuildFCmp(comp_ctx->builder, op, lhs, rhs, "cmp"))) { + if (!(cmp = LLVMBuildFCmp(comp_ctx->builder, + op == FLOAT_MIN ? LLVMRealOLT : LLVMRealOGT, rhs, + lhs, "cmp"))) { HANDLE_FAILURE("LLVMBuildFCmp"); return false; } - if (!(result = - LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) { + if (!(selected = + LLVMBuildSelect(comp_ctx->builder, cmp, rhs, lhs, "selected"))) { HANDLE_FAILURE("LLVMBuildSelect"); return false; } - return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result"); + return simd_bitcast_and_push_v128(comp_ctx, func_ctx, selected, "result"); +} + +static bool +simd_float_min(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + LLVMTypeRef vector_type) +{ + LLVMValueRef lhs, rhs, lhs_nan, rhs_nan, olt_ret, ogt_ret, or_ret, ret1, + ret2, ret3, ret4; + + if (!(rhs = + simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) + || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, + "lhs"))) { + return false; + } + + if (!(lhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, lhs, lhs, + "lhs_nan"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO"); + return false; + } + + if (!(rhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, rhs, rhs, + "rhs_nan"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO"); + return false; + } + + if (!(olt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLT, lhs, rhs, + "olt_ret"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOLT"); + return false; + } + + if (!(ogt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOGT, lhs, rhs, + "ogt_ret"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOGT"); + return false; + } + + /* lhs or rhs */ + { + LLVMValueRef integer_l, integer_r, integer_or; + + if (!(integer_l = LLVMBuildBitCast(comp_ctx->builder, lhs, + V128_i64x2_TYPE, "lhs_to_int"))) { + HANDLE_FAILURE("LLVMBuildBitCas"); + return false; + } + + if (!(integer_r = LLVMBuildBitCast(comp_ctx->builder, rhs, + V128_i64x2_TYPE, "rhs_to_int"))) { + HANDLE_FAILURE("LLVMBuildBitCas"); + return false; + } + + if (!(integer_or = + LLVMBuildOr(comp_ctx->builder, integer_l, integer_r, "or"))) { + HANDLE_FAILURE("LLVMBuildOr"); + return false; + } + + if (!(or_ret = LLVMBuildBitCast(comp_ctx->builder, integer_or, + vector_type, "holder"))) { + HANDLE_FAILURE("LLVMBuildBitCast"); + return false; + } + } + + if (!(ret1 = LLVMBuildSelect(comp_ctx->builder, olt_ret, lhs, or_ret, + "sel_olt"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret2 = LLVMBuildSelect(comp_ctx->builder, ogt_ret, rhs, ret1, + "sel_ogt"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret3 = LLVMBuildSelect(comp_ctx->builder, lhs_nan, lhs, ret2, + "sel_lhs_nan"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret4 = LLVMBuildSelect(comp_ctx->builder, rhs_nan, rhs, ret3, + "sel_rhs_nan"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + return simd_bitcast_and_push_v128(comp_ctx, func_ctx, ret4, "result"); +} + +static bool +simd_float_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + LLVMTypeRef vector_type) +{ + LLVMValueRef lhs, rhs, lhs_nan, rhs_nan, olt_ret, ogt_ret, and_ret, ret1, + ret2, ret3, ret4; + + if (!(rhs = + simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) + || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, + "lhs"))) { + return false; + } + + if (!(lhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, lhs, lhs, + "lhs_nan"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO"); + return false; + } + + if (!(rhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, rhs, rhs, + "rhs_nan"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO"); + return false; + } + + if (!(olt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLT, lhs, rhs, + "olt_ret"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOLT"); + return false; + } + + if (!(ogt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOGT, lhs, rhs, + "ogt_ret"))) { + HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOGT"); + return false; + } + + /* lhs and rhs */ + { + LLVMValueRef integer_l, integer_r, integer_and; + + if (!(integer_l = LLVMBuildBitCast(comp_ctx->builder, lhs, + V128_i64x2_TYPE, "lhs_to_int"))) { + HANDLE_FAILURE("LLVMBuildBitCas"); + return false; + } + + if (!(integer_r = LLVMBuildBitCast(comp_ctx->builder, rhs, + V128_i64x2_TYPE, "rhs_to_int"))) { + HANDLE_FAILURE("LLVMBuildBitCas"); + return false; + } + + if (!(integer_and = LLVMBuildAnd(comp_ctx->builder, integer_l, + integer_r, "and"))) { + HANDLE_FAILURE("LLVMBuildOr"); + return false; + } + + if (!(and_ret = LLVMBuildBitCast(comp_ctx->builder, integer_and, + vector_type, "holder"))) { + HANDLE_FAILURE("LLVMBuildBitCast"); + return false; + } + } + + if (!(ret1 = LLVMBuildSelect(comp_ctx->builder, ogt_ret, lhs, and_ret, + "sel_ogt"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret2 = LLVMBuildSelect(comp_ctx->builder, olt_ret, rhs, ret1, + "sel_olt"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret3 = LLVMBuildSelect(comp_ctx->builder, lhs_nan, lhs, ret2, + "sel_lhs_nan"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + if (!(ret4 = LLVMBuildSelect(comp_ctx->builder, rhs_nan, rhs, ret3, + "sel_rhs_nan"))) { + HANDLE_FAILURE("LLVMBuildSelect"); + return false; + } + + return simd_bitcast_and_push_v128(comp_ctx, func_ctx, ret4, "result"); } -/*TODO: sugggest non-IA platforms check with "llvm.minimum.*" and - * "llvm.maximum.*" firstly */ bool aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool run_min) { - return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, - V128_f32x4_TYPE); + return run_min ? simd_float_min(comp_ctx, func_ctx, V128_f32x4_TYPE) + : simd_float_max(comp_ctx, func_ctx, V128_f32x4_TYPE); } bool aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool run_min) { - return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, - V128_f64x2_TYPE); -} - -static bool -simd_float_pmin_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, - LLVMTypeRef vector_type, const char *intrinsic) -{ - LLVMValueRef lhs, rhs, result; - LLVMTypeRef param_types[2]; - - param_types[0] = vector_type; - param_types[1] = vector_type; - - if (!(rhs = - simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs")) - || !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, - "lhs"))) { - return false; - } - - if (!(result = - aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic, - vector_type, param_types, 2, lhs, rhs))) { - return false; - } - - return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result"); + return run_min ? simd_float_min(comp_ctx, func_ctx, V128_f64x2_TYPE) + : simd_float_max(comp_ctx, func_ctx, V128_f64x2_TYPE); } bool aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool run_min) { - return simd_float_pmin_max(comp_ctx, func_ctx, V128_f32x4_TYPE, - run_min ? "llvm.minnum.v4f32" - : "llvm.maxnum.v4f32"); + return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, + V128_f32x4_TYPE); } bool aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, bool run_min) { - return simd_float_pmin_max(comp_ctx, func_ctx, V128_f64x2_TYPE, - run_min ? "llvm.minnum.v2f64" - : "llvm.maxnum.v2f64"); + return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX, + V128_f64x2_TYPE); } bool From 00539620e9522b41eec5776d8d6168ebba2f6f06 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Fri, 29 Sep 2023 04:52:54 +0200 Subject: [PATCH 46/58] Improve stack trace dump and fix coding guideline CI (#2599) Avoid the stack traces getting mixed up together when multi-threading is enabled by using exception_lock/unlock in dumping the call stacks. And remove duplicated call stack dump in wasm_application.c. Also update coding guideline CI to fix the clang-format-12 not found issue. --- .github/workflows/coding_guidelines.yml | 2 +- core/iwasm/aot/aot_runtime.c | 4 ++++ core/iwasm/common/wasm_application.c | 10 +--------- core/iwasm/interpreter/wasm_interp_classic.c | 3 --- core/iwasm/interpreter/wasm_interp_fast.c | 3 --- core/iwasm/interpreter/wasm_runtime.c | 4 ++++ product-mini/platforms/posix/main.c | 13 +++++++++---- product-mini/platforms/windows/main.c | 13 +++++++++---- 8 files changed, 28 insertions(+), 24 deletions(-) diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index 259e84fe5..17d60ac43 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -16,7 +16,7 @@ concurrency: jobs: compliance_job: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: checkout uses: actions/checkout@v3 diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index abd4539be..0799d625f 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2807,6 +2807,7 @@ aot_create_call_stack(struct WASMExecEnv *exec_env) total_len += \ wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \ if ((!print) && buf && (len == 0)) { \ + exception_unlock(module_inst); \ return total_len; \ } \ } while (0) @@ -2829,6 +2830,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) return 0; } + exception_lock(module_inst); snprintf(line_buf, sizeof(line_buf), "\n"); PRINT_OR_DUMP(); @@ -2837,6 +2839,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) uint32 line_length, i; if (!bh_vector_get(module_inst->frames, n, &frame)) { + exception_unlock(module_inst); return 0; } @@ -2867,6 +2870,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) } snprintf(line_buf, sizeof(line_buf), "\n"); PRINT_OR_DUMP(); + exception_unlock(module_inst); return total_len + 1; } diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 795d65c8c..02999584f 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -231,7 +231,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) { bool ret; -#if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_DUMP_CALL_STACK != 0) +#if (WASM_ENABLE_MEMORY_PROFILING != 0) WASMExecEnv *exec_env; #endif @@ -251,14 +251,6 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, if (ret) ret = wasm_runtime_get_exception(module_inst) == NULL; -#if WASM_ENABLE_DUMP_CALL_STACK != 0 - if (!ret) { - exec_env = wasm_runtime_get_exec_env_singleton(module_inst); - if (exec_env) - wasm_runtime_dump_call_stack(exec_env); - } -#endif - return ret; } diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 2a48c1bde..ce090d1f0 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -4209,7 +4209,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); unsigned i; bool copy_argv_from_frame = true; - char exception[EXCEPTION_BUF_LEN]; if (argc < function->param_cell_num) { char buf[128]; @@ -4342,8 +4341,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, wasm_interp_dump_call_stack(exec_env, true, NULL, 0); } #endif - wasm_copy_exception(module_inst, exception); - LOG_DEBUG("meet an exception %s", exception); } wasm_exec_env_set_cur_frame(exec_env, prev_frame); diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 229a2151d..e565c2c89 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -3945,7 +3945,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, /* This frame won't be used by JITed code, so only allocate interp frame here. */ unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); - char exception[EXCEPTION_BUF_LEN]; if (argc < function->param_cell_num) { char buf[128]; @@ -4030,8 +4029,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, wasm_interp_dump_call_stack(exec_env, true, NULL, 0); } #endif - wasm_copy_exception(module_inst, exception); - LOG_DEBUG("meet an exception %s", exception); } wasm_exec_env_set_cur_frame(exec_env, prev_frame); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index af2a61c88..8fb19d52e 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2915,6 +2915,7 @@ wasm_interp_create_call_stack(struct WASMExecEnv *exec_env) total_len += \ wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \ if ((!print) && buf && (len == 0)) { \ + exception_unlock(module_inst); \ return total_len; \ } \ } while (0) @@ -2939,6 +2940,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, return 0; } + exception_lock(module_inst); snprintf(line_buf, sizeof(line_buf), "\n"); PRINT_OR_DUMP(); @@ -2947,6 +2949,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, uint32 line_length, i; if (!bh_vector_get(module_inst->frames, n, &frame)) { + exception_unlock(module_inst); return 0; } @@ -2977,6 +2980,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf, } snprintf(line_buf, sizeof(line_buf), "\n"); PRINT_OR_DUMP(); + exception_unlock(module_inst); return total_len + 1; } diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 0051e628c..b7d755410 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -120,8 +120,7 @@ app_instance_main(wasm_module_inst_t module_inst) const char *exception; wasm_application_execute_main(module_inst, app_argc, app_argv); - if ((exception = wasm_runtime_get_exception(module_inst))) - printf("%s\n", exception); + exception = wasm_runtime_get_exception(module_inst); return exception; } @@ -977,17 +976,20 @@ main(int argc, char *argv[]) #endif ret = 0; + const char *exception = NULL; if (is_repl_mode) { app_instance_repl(wasm_module_inst); } else if (func_name) { - if (app_instance_func(wasm_module_inst, func_name)) { + exception = app_instance_func(wasm_module_inst, func_name); + if (exception) { /* got an exception */ ret = 1; } } else { - if (app_instance_main(wasm_module_inst)) { + exception = app_instance_main(wasm_module_inst); + if (exception) { /* got an exception */ ret = 1; } @@ -1000,6 +1002,9 @@ main(int argc, char *argv[]) } #endif + if (exception) + printf("%s\n", exception); + #if WASM_ENABLE_STATIC_PGO != 0 && WASM_ENABLE_AOT != 0 if (get_package_type(wasm_file_buf, wasm_file_size) == Wasm_Module_AoT && gen_prof_file) diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 121be4195..985c9e6c7 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -77,8 +77,7 @@ app_instance_main(wasm_module_inst_t module_inst) const char *exception; wasm_application_execute_main(module_inst, app_argc, app_argv); - if ((exception = wasm_runtime_get_exception(module_inst))) - printf("%s\n", exception); + exception = wasm_runtime_get_exception(module_inst); return exception; } @@ -545,17 +544,20 @@ main(int argc, char *argv[]) #endif ret = 0; + const char *exception = NULL; if (is_repl_mode) { app_instance_repl(wasm_module_inst); } else if (func_name) { - if (app_instance_func(wasm_module_inst, func_name)) { + exception = app_instance_func(wasm_module_inst, func_name); + if (exception) { /* got an exception */ ret = 1; } } else { - if (app_instance_main(wasm_module_inst)) { + exception = app_instance_main(wasm_module_inst); + if (exception) { /* got an exception */ ret = 1; } @@ -568,6 +570,9 @@ main(int argc, char *argv[]) } #endif + if (exception) + printf("%s\n", exception); + #if WASM_ENABLE_DEBUG_INTERP != 0 fail4: #endif From e1ea15d94e9afb73f1bbe9c5191558b715539667 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 29 Sep 2023 16:30:52 +0900 Subject: [PATCH 47/58] aot_resolve_stack_sizes: Disable the size check for now (#2608) cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2555#issuecomment-1738530877 https://github.com/llvm/llvm-project/issues/67765 --- core/iwasm/compilation/aot_emit_aot_file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 622187755..103b2750e 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -2703,6 +2703,7 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data) || (obj_data->target_info.bin_type == AOT_COFF32_BIN_TYPE && !strncmp(name, "_", 1) && !strcmp(name + 1, aot_stack_sizes_alias_name)))) { +#if 0 /* cf. https://github.com/llvm/llvm-project/issues/67765 */ uint64 sz = LLVMGetSymbolSize(sym_itr); if (sz != sizeof(uint32) * obj_data->func_count /* sz of COFF64/COFF32 is 0, ignore the check */ @@ -2711,6 +2712,7 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data) aot_set_last_error("stack_sizes had unexpected size."); goto fail; } +#endif uint64 addr = LLVMGetSymbolAddress(sym_itr); if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) { From 1a8810416034e59657d38f8a746fd896012181ae Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 2 Oct 2023 17:33:11 -0700 Subject: [PATCH 48/58] Remove module instance from hashmap in wasi_nn_destroy (#2613) When destroying wasi-nn context, module instance should be also removed from hashmap to avoid memory leak. --- core/iwasm/libraries/wasi-nn/src/wasi_nn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/iwasm/libraries/wasi-nn/src/wasi_nn.c b/core/iwasm/libraries/wasi-nn/src/wasi_nn.c index ba27055ea..c234e450a 100644 --- a/core/iwasm/libraries/wasi-nn/src/wasi_nn.c +++ b/core/iwasm/libraries/wasi-nn/src/wasi_nn.c @@ -163,6 +163,7 @@ void wasi_nn_destroy(wasm_module_inst_t instance) { WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance); + bh_hash_map_remove(hashmap, (void *)instance, NULL, NULL); wasi_nn_ctx_destroy(wasi_nn_ctx); } From 64baf54d8881e9475a9e579a82c0f6148022f350 Mon Sep 17 00:00:00 2001 From: funera1 <60760935+funera1@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:33:00 +0900 Subject: [PATCH 49/58] Fix label index out-of-range references in op_br_table_cache (#2615) Fixed a bug in the processing of the br_table_cache opcode that caused out-of-range references when the label index was greater than the length of the label. --- core/iwasm/interpreter/wasm_interp_classic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index ce090d1f0..50860d3a3 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1418,6 +1418,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, while (node_cache) { node_next = bh_list_elem_next(node_cache); if (node_cache->br_table_op_addr == frame_ip - 1) { + if (lidx > node_cache->br_count) + lidx = node_cache->br_count; depth = node_cache->br_depths[lidx]; goto label_pop_csp_n; } From 28ebd57400df4944e270cd71b2c063acf8c02630 Mon Sep 17 00:00:00 2001 From: Maks Litskevich Date: Wed, 4 Oct 2023 01:10:10 +0100 Subject: [PATCH 50/58] Refactor stress tests to make them runnable in reactor mode (#2614) --- .github/workflows/nightly_run.yml | 4 +- .../lib-wasi-threads/stress-test/build.sh | 1 + .../errorcheck_mutex_stress_test.c | 11 +++- .../stress-test/normal_mutex_stress_test.c | 11 +++- .../stress-test/recursive_mutex_stress_test.c | 11 +++- .../stress-test/spawn_stress_test.c | 54 +++++++++++-------- .../stress_test_threads_creation.c | 42 ++++++++------- 7 files changed, 86 insertions(+), 48 deletions(-) diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index 1cf4b51e3..ea79b3f23 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -8,9 +8,11 @@ on: types: - opened - synchronize - #running nightly pipeline if you're changing it + # running nightly pipeline if you're changing it + # stress tests are run only in nightly at the moment, so running them in they are changed paths: - ".github/workflows/nightly_run.yml" + - "core/iwasm/libraries/lib-wasi-threads/stress-test/**" # midnight UTC schedule: diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh b/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh index 341f3ef12..1ea95cb97 100755 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/build.sh @@ -60,6 +60,7 @@ for test_c in *.c; do -Wl,--export=wasi_thread_start \ -Wl,--export=malloc \ -Wl,--export=free \ + -Wl,--export=test \ $sysroot_command \ $test_c -o $test_wasm done diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c index 3b594657f..946e8bd63 100644 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/errorcheck_mutex_stress_test.c @@ -7,8 +7,8 @@ #include #include "mutex_common.h" -int -main() +void +test() { pthread_mutex_t mutex; @@ -25,3 +25,10 @@ main() fprintf(stderr, "Errorcheck mutex test is completed\n"); pthread_mutex_destroy(&mutex); } + +int +main() +{ + test(); + return 0; +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c index 6c75f8814..c7ffae279 100644 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/normal_mutex_stress_test.c @@ -7,8 +7,8 @@ #include #include "mutex_common.h" -int -main() +void +test() { pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); @@ -18,3 +18,10 @@ main() fprintf(stderr, "Normal mutex test is completed\n"); pthread_mutex_destroy(&mutex); } + +int +main() +{ + test(); + return 0; +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c index 8c3e325e8..5874372cb 100644 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/recursive_mutex_stress_test.c @@ -31,8 +31,8 @@ same_thread_multiple_rec_mutex_lock(void *mutex) return NULL; } -int -main() +void +test() { pthread_mutex_t mutex; @@ -63,3 +63,10 @@ main() fprintf(stderr, "Recursive mutex test is completed\n"); pthread_mutex_destroy(&mutex); } + +int +main() +{ + test(); + return 0; +} diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c index a35337f35..8cb61a2a6 100644 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/spawn_stress_test.c @@ -16,13 +16,6 @@ #include #include -enum CONSTANTS { - NUM_ITER = 100000, - NUM_RETRY = 8, - MAX_NUM_THREADS = 12, - RETRY_SLEEP_TIME_US = 2000, -}; - unsigned prime_numbers_count = 0; bool @@ -49,10 +42,10 @@ check_if_prime(void *value) } unsigned int -validate() +validate(int iter_num) { unsigned int counter = 0; - for (unsigned int i = 2; i <= NUM_ITER; ++i) { + for (unsigned int i = 2; i <= iter_num; ++i) { counter += is_prime(i); } @@ -60,11 +53,12 @@ validate() } void -spawn_thread(pthread_t *thread, unsigned int *arg) +spawn_thread(pthread_t *thread, int retry_time_us, int retry_num, + unsigned int *arg) { int status_code = -1; - int timeout_us = RETRY_SLEEP_TIME_US; - for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) { + int timeout_us = retry_time_us; + for (int tries = 0; status_code != 0 && tries < retry_num; ++tries) { status_code = pthread_create(thread, NULL, &check_if_prime, arg); assert(status_code == 0 || status_code == EAGAIN); if (status_code == EAGAIN) { @@ -76,42 +70,56 @@ spawn_thread(pthread_t *thread, unsigned int *arg) assert(status_code == 0 && "Thread creation should succeed"); } -int -main(int argc, char **argv) +void +test(int iter_num, int retry_num, int max_threads_num, int retry_time_us) { - pthread_t threads[MAX_NUM_THREADS]; - unsigned int args[MAX_NUM_THREADS]; + pthread_t threads[max_threads_num]; + unsigned int args[max_threads_num]; double percentage = 0.1; - for (unsigned int factorised_number = 2; factorised_number < NUM_ITER; + for (unsigned int factorised_number = 2; factorised_number < iter_num; ++factorised_number) { - if (factorised_number > NUM_ITER * percentage) { + if (factorised_number > iter_num * percentage) { fprintf(stderr, "Stress test is %d%% finished\n", (unsigned int)(percentage * 100)); percentage += 0.1; } - unsigned int thread_num = factorised_number % MAX_NUM_THREADS; + unsigned int thread_num = factorised_number % max_threads_num; if (threads[thread_num] != 0) { assert(pthread_join(threads[thread_num], NULL) == 0); } args[thread_num] = factorised_number; - usleep(RETRY_SLEEP_TIME_US); - spawn_thread(&threads[thread_num], &args[thread_num]); + usleep(retry_time_us); + spawn_thread(&threads[thread_num], retry_time_us, retry_num, + &args[thread_num]); assert(threads[thread_num] != 0); } - for (int i = 0; i < MAX_NUM_THREADS; ++i) { + for (int i = 0; i < max_threads_num; ++i) { assert(threads[i] == 0 || pthread_join(threads[i], NULL) == 0); } // Check the test results assert( - prime_numbers_count == validate() + prime_numbers_count == validate(iter_num) && "Answer mismatch between tested code and reference implementation"); fprintf(stderr, "Stress test finished successfully\n"); +} + +enum DEFAULT_PARAMETERS { + ITER_NUM = 20000, + RETRY_NUM = 8, + MAX_THREADS_NUM = 12, + RETRY_SLEEP_TIME_US = 2000, +}; + +int +main(int argc, char **argv) +{ + test(ITER_NUM, RETRY_NUM, MAX_THREADS_NUM, RETRY_SLEEP_TIME_US); return 0; } diff --git a/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c b/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c index f991fa7ab..c4c2d2857 100644 --- a/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c +++ b/core/iwasm/libraries/lib-wasi-threads/stress-test/stress_test_threads_creation.c @@ -9,14 +9,6 @@ #include #include -enum CONSTANTS { - NUM_ITER = 200000, - NUM_RETRY = 8, - MAX_NUM_THREADS = 12, - RETRY_SLEEP_TIME_US = 4000, - SECOND = 1000 * 1000 * 1000 -}; - int threads_executed = 0; unsigned int threads_creation_tried = 0; unsigned int threads_in_use = 0; @@ -31,11 +23,11 @@ thread_func(void *arg) } void -spawn_thread(pthread_t *thread) +spawn_thread(pthread_t *thread, int retry_time, int iter_num) { int status_code = -1; - int timeout_us = RETRY_SLEEP_TIME_US; - for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) { + int timeout_us = retry_time; + for (int tries = 0; status_code != 0 && tries < iter_num; ++tries) { status_code = pthread_create(thread, NULL, &thread_func, NULL); __atomic_fetch_add(&threads_creation_tried, 1, __ATOMIC_RELAXED); @@ -49,32 +41,33 @@ spawn_thread(pthread_t *thread) assert(status_code == 0 && "Thread creation should succeed"); } -int -main(int argc, char **argv) +void +test(int iter_num, int max_threads_num, int retry_num, int retry_time_us) { double percentage = 0.1; + int second_us = 1000 * 1000 * 1000; // 1 second in us - for (int iter = 0; iter < NUM_ITER; ++iter) { - if (iter > NUM_ITER * percentage) { + for (int iter = 0; iter < iter_num; ++iter) { + if (iter > iter_num * percentage) { fprintf(stderr, "Spawning stress test is %d%% finished\n", (unsigned int)(percentage * 100)); percentage += 0.1; } while (__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) - == MAX_NUM_THREADS) { + == max_threads_num) { usleep(100); } __atomic_fetch_add(&threads_in_use, 1, __ATOMIC_SEQ_CST); pthread_t tmp; - spawn_thread(&tmp); + spawn_thread(&tmp, retry_time_us, iter_num); pthread_detach(tmp); } while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) { // Casting to int* to supress compiler warning __builtin_wasm_memory_atomic_wait32((int *)(&threads_in_use), 0, - SECOND); + second_us); } assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0); @@ -91,5 +84,18 @@ main(int argc, char **argv) "with retry ratio %f\n", threads_creation_tried, (1. * threads_creation_tried) / threads_executed); +} + +enum DEFAULT_PARAMETERS { + ITER_NUM = 50000, + RETRY_NUM = 8, + MAX_NUM_THREADS = 12, + RETRY_SLEEP_TIME_US = 4000, +}; + +int +main(int argc, char **argv) +{ + test(ITER_NUM, MAX_NUM_THREADS, RETRY_NUM, RETRY_SLEEP_TIME_US); return 0; } From 8987432f369d8cd70bc632be55ed2eb2a1cb5aed Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:02:25 +0100 Subject: [PATCH 51/58] libc-wasi: Conditionally support SYNC flags (#2581) To make it clearer to users when synchronization behaviour is not supported, return ENOTSUP when O_RSYNC, O_DSYNC or O_SYNC are respectively not defined. Linux also doesn't support O_RSYNC despite the O_RSYNC flag being defined. --- .../sandboxed-system-primitives/src/posix.c | 38 ++++++++++++------- .../src/ssp_config.h | 16 +++++++- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index eda65b8da..5c85a81d6 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -1282,18 +1282,20 @@ wasmtime_ssp_fd_fdstat_get(wasm_exec_env_t exec_env, struct fd_table *curfds, if ((ret & O_APPEND) != 0) buf->fs_flags |= __WASI_FDFLAG_APPEND; -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC if ((ret & O_DSYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_DSYNC; #endif if ((ret & O_NONBLOCK) != 0) buf->fs_flags |= __WASI_FDFLAG_NONBLOCK; -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC if ((ret & O_RSYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_RSYNC; #endif +#ifdef CONFIG_HAS_O_SYNC if ((ret & O_SYNC) != 0) buf->fs_flags |= __WASI_FDFLAG_SYNC; +#endif return 0; } @@ -1306,21 +1308,25 @@ wasmtime_ssp_fd_fdstat_set_flags(wasm_exec_env_t exec_env, if ((fs_flags & __WASI_FDFLAG_APPEND) != 0) noflags |= O_APPEND; if ((fs_flags & __WASI_FDFLAG_DSYNC) != 0) -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC noflags |= O_DSYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif if ((fs_flags & __WASI_FDFLAG_NONBLOCK) != 0) noflags |= O_NONBLOCK; if ((fs_flags & __WASI_FDFLAG_RSYNC) != 0) -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC noflags |= O_RSYNC; #else - noflags |= O_SYNC; + return __WASI_ENOTSUP; #endif if ((fs_flags & __WASI_FDFLAG_SYNC) != 0) +#ifdef CONFIG_HAS_O_SYNC noflags |= O_SYNC; +#else + return __WASI_ENOTSUP; +#endif struct fd_object *fo; __wasi_errno_t error = @@ -1971,26 +1977,30 @@ wasmtime_ssp_path_open(wasm_exec_env_t exec_env, struct fd_table *curfds, if ((fs_flags & __WASI_FDFLAG_APPEND) != 0) noflags |= O_APPEND; if ((fs_flags & __WASI_FDFLAG_DSYNC) != 0) { -#ifdef O_DSYNC +#ifdef CONFIG_HAS_O_DSYNC noflags |= O_DSYNC; -#else - noflags |= O_SYNC; -#endif needed_inheriting |= __WASI_RIGHT_FD_DATASYNC; +#else + return __WASI_ENOTSUP; +#endif } if ((fs_flags & __WASI_FDFLAG_NONBLOCK) != 0) noflags |= O_NONBLOCK; if ((fs_flags & __WASI_FDFLAG_RSYNC) != 0) { -#ifdef O_RSYNC +#ifdef CONFIG_HAS_O_RSYNC noflags |= O_RSYNC; -#else - noflags |= O_SYNC; -#endif needed_inheriting |= __WASI_RIGHT_FD_SYNC; +#else + return __WASI_ENOTSUP; +#endif } if ((fs_flags & __WASI_FDFLAG_SYNC) != 0) { +#ifdef CONFIG_HAS_O_SYNC noflags |= O_SYNC; needed_inheriting |= __WASI_RIGHT_FD_SYNC; +#else + return __WASI_ENOTSUP; +#endif } if (write && (noflags & (O_APPEND | O_TRUNC)) == 0) needed_inheriting |= __WASI_RIGHT_FD_SEEK; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index f5e130a9e..f75da5d8a 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -14,8 +14,8 @@ #ifndef SSP_CONFIG_H #define SSP_CONFIG_H +#include "bh_platform.h" #include "gnuc.h" -#include #if defined(__FreeBSD__) || defined(__APPLE__) \ || (defined(ANDROID) && __ANDROID_API__ < 28) @@ -101,6 +101,20 @@ #define st_mtim st_mtimespec #endif +#if defined(O_DSYNC) +#define CONFIG_HAS_O_DSYNC +#endif + +// POSIX requires O_RSYNC to be defined, but Linux explicitly doesn't support +// it. +#if defined(O_RSYNC) && !defined(__linux__) +#define CONFIG_HAS_O_RSYNC +#endif + +#if defined(O_SYNC) +#define CONFIG_HAS_O_SYNC +#endif + #if !defined(BH_PLATFORM_LINUX_SGX) /* Clang's __GNUC_PREREQ macro has a different meaning than GCC one, so we have to handle this case specially */ From d8ee771e28e4e32f29894803824dda736452c970 Mon Sep 17 00:00:00 2001 From: Gavin Hayes Date: Wed, 4 Oct 2023 09:55:37 -0400 Subject: [PATCH 52/58] Add Cosmopolitan Libc Platform (#2598) This PR adds the Cosmopolitan Libc platform enabling compatibility with multiple x86_64 operating systems with the same binary. The platform is similar to the Linux platform, but for now only x86_64 with interpreter modes are supported. The only major change to the core is `posix.c/convert_errno()` was rewritten to use a switch statement. With Cosmopolitan errno values depend on the currently running operating system, and so they are non-constant and cannot be used in array designators. However, the `cosmocc` compiler allows non-constant case labels in switch statements, enabling the new version. And updated wamr-test-suites script to add `-j ` option. The spec tests can be ran via `CC=cosmocc ./test_wamr.sh -j cosmopolitan -t classic-interp` or `CC=cosmocc ./test_wamr.sh -j cosmopolitan -t fast-interp`. --- .../sandboxed-system-primitives/src/posix.c | 179 +++++++++--------- .../src/ssp_config.h | 5 +- .../platform/common/posix/posix_socket.c | 4 +- .../platform/cosmopolitan/platform_init.c | 43 +++++ .../platform/cosmopolitan/platform_internal.h | 122 ++++++++++++ .../cosmopolitan/shared_platform.cmake | 19 ++ product-mini/README.md | 20 ++ .../platforms/cosmopolitan/CMakeLists.txt | 175 +++++++++++++++++ .../platforms/cosmopolitan/build_cosmocc.sh | 10 + product-mini/platforms/cosmopolitan/main.c | 6 + tests/wamr-test-suites/test_wamr.sh | 23 ++- 11 files changed, 512 insertions(+), 94 deletions(-) create mode 100644 core/shared/platform/cosmopolitan/platform_init.c create mode 100644 core/shared/platform/cosmopolitan/platform_internal.h create mode 100644 core/shared/platform/cosmopolitan/shared_platform.cmake create mode 100644 product-mini/platforms/cosmopolitan/CMakeLists.txt create mode 100755 product-mini/platforms/cosmopolitan/build_cosmocc.sh create mode 100644 product-mini/platforms/cosmopolitan/main.c diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 5c85a81d6..415a66463 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -60,98 +60,99 @@ static_assert(sizeof(struct iovec) == sizeof(__wasi_ciovec_t), static __wasi_errno_t convert_errno(int error) { - static const __wasi_errno_t errors[] = { -#define X(v) [v] = __WASI_##v - X(E2BIG), - X(EACCES), - X(EADDRINUSE), - X(EADDRNOTAVAIL), - X(EAFNOSUPPORT), - X(EAGAIN), - X(EALREADY), - X(EBADF), - X(EBADMSG), - X(EBUSY), - X(ECANCELED), - X(ECHILD), - X(ECONNABORTED), - X(ECONNREFUSED), - X(ECONNRESET), - X(EDEADLK), - X(EDESTADDRREQ), - X(EDOM), - X(EDQUOT), - X(EEXIST), - X(EFAULT), - X(EFBIG), - X(EHOSTUNREACH), - X(EIDRM), - X(EILSEQ), - X(EINPROGRESS), - X(EINTR), - X(EINVAL), - X(EIO), - X(EISCONN), - X(EISDIR), - X(ELOOP), - X(EMFILE), - X(EMLINK), - X(EMSGSIZE), - X(EMULTIHOP), - X(ENAMETOOLONG), - X(ENETDOWN), - X(ENETRESET), - X(ENETUNREACH), - X(ENFILE), - X(ENOBUFS), - X(ENODEV), - X(ENOENT), - X(ENOEXEC), - X(ENOLCK), - X(ENOLINK), - X(ENOMEM), - X(ENOMSG), - X(ENOPROTOOPT), - X(ENOSPC), - X(ENOSYS), + __wasi_errno_t code = __WASI_ENOSYS; +#define X(v) \ + case v: \ + code = __WASI_##v; \ + break; + switch (error) { + X(E2BIG) + X(EACCES) + X(EADDRINUSE) + X(EADDRNOTAVAIL) + X(EAFNOSUPPORT) + X(EAGAIN) + X(EALREADY) + X(EBADF) + X(EBADMSG) + X(EBUSY) + X(ECANCELED) + X(ECHILD) + X(ECONNABORTED) + X(ECONNREFUSED) + X(ECONNRESET) + X(EDEADLK) + X(EDESTADDRREQ) + X(EDOM) + X(EDQUOT) + X(EEXIST) + X(EFAULT) + X(EFBIG) + X(EHOSTUNREACH) + X(EIDRM) + X(EILSEQ) + X(EINPROGRESS) + X(EINTR) + X(EINVAL) + X(EIO) + X(EISCONN) + X(EISDIR) + X(ELOOP) + X(EMFILE) + X(EMLINK) + X(EMSGSIZE) + X(EMULTIHOP) + X(ENAMETOOLONG) + X(ENETDOWN) + X(ENETRESET) + X(ENETUNREACH) + X(ENFILE) + X(ENOBUFS) + X(ENODEV) + X(ENOENT) + X(ENOEXEC) + X(ENOLCK) + X(ENOLINK) + X(ENOMEM) + X(ENOMSG) + X(ENOPROTOOPT) + X(ENOSPC) + X(ENOSYS) #ifdef ENOTCAPABLE - X(ENOTCAPABLE), + X(ENOTCAPABLE) #endif - X(ENOTCONN), - X(ENOTDIR), - X(ENOTEMPTY), - X(ENOTRECOVERABLE), - X(ENOTSOCK), - X(ENOTSUP), - X(ENOTTY), - X(ENXIO), - X(EOVERFLOW), - X(EOWNERDEAD), - X(EPERM), - X(EPIPE), - X(EPROTO), - X(EPROTONOSUPPORT), - X(EPROTOTYPE), - X(ERANGE), - X(EROFS), - X(ESPIPE), - X(ESRCH), - X(ESTALE), - X(ETIMEDOUT), - X(ETXTBSY), - X(EXDEV), + X(ENOTCONN) + X(ENOTDIR) + X(ENOTEMPTY) + X(ENOTRECOVERABLE) + X(ENOTSOCK) + X(ENOTSUP) + X(ENOTTY) + X(ENXIO) + X(EOVERFLOW) + X(EOWNERDEAD) + X(EPERM) + X(EPIPE) + X(EPROTO) + X(EPROTONOSUPPORT) + X(EPROTOTYPE) + X(ERANGE) + X(EROFS) + X(ESPIPE) + X(ESRCH) + X(ESTALE) + X(ETIMEDOUT) + X(ETXTBSY) + X(EXDEV) + default: + if (error == EOPNOTSUPP) + code = __WASI_ENOTSUP; + else if (code == EWOULDBLOCK) + code = __WASI_EAGAIN; + break; + } #undef X -#if EOPNOTSUPP != ENOTSUP - [EOPNOTSUPP] = __WASI_ENOTSUP, -#endif -#if EWOULDBLOCK != EAGAIN - [EWOULDBLOCK] = __WASI_EAGAIN, -#endif - }; - if (error < 0 || (size_t)error >= sizeof(errors) / sizeof(errors[0]) - || errors[error] == 0) - return __WASI_ENOSYS; - return errors[error]; + return code; } static bool diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index f75da5d8a..a69d6ca38 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -65,7 +65,7 @@ #endif #endif -#if !defined(__APPLE__) && !defined(ESP_PLATFORM) +#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(__COSMOPOLITAN__) #define CONFIG_HAS_POSIX_FALLOCATE 1 #else #define CONFIG_HAS_POSIX_FALLOCATE 0 @@ -83,7 +83,8 @@ #define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0 #endif -#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) +#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \ + && !defined(__COSMOPOLITAN__) #define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1 #else #define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0 diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index 9f5538b5c..11c56e723 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -799,7 +799,7 @@ os_socket_set_ip_add_membership(bh_socket_t socket, { assert(imr_multiaddr); if (is_ipv6) { -#ifdef IPPROTO_IPV6 +#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN) struct ipv6_mreq mreq; for (int i = 0; i < 8; i++) { ((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] = @@ -837,7 +837,7 @@ os_socket_set_ip_drop_membership(bh_socket_t socket, { assert(imr_multiaddr); if (is_ipv6) { -#ifdef IPPROTO_IPV6 +#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN) struct ipv6_mreq mreq; for (int i = 0; i < 8; i++) { ((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] = diff --git a/core/shared/platform/cosmopolitan/platform_init.c b/core/shared/platform/cosmopolitan/platform_init.c new file mode 100644 index 000000000..2aae13fa1 --- /dev/null +++ b/core/shared/platform/cosmopolitan/platform_init.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" + +int +bh_platform_init() +{ + return 0; +} + +void +bh_platform_destroy() +{} + +int +os_printf(const char *format, ...) +{ + int ret = 0; + va_list ap; + + va_start(ap, format); +#ifndef BH_VPRINTF + ret += vprintf(format, ap); +#else + ret += BH_VPRINTF(format, ap); +#endif + va_end(ap); + + return ret; +} + +int +os_vprintf(const char *format, va_list ap) +{ +#ifndef BH_VPRINTF + return vprintf(format, ap); +#else + return BH_VPRINTF(format, ap); +#endif +} diff --git a/core/shared/platform/cosmopolitan/platform_internal.h b/core/shared/platform/cosmopolitan/platform_internal.h new file mode 100644 index 000000000..ed2545436 --- /dev/null +++ b/core/shared/platform/cosmopolitan/platform_internal.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * Copyright (C) 2023 Dylibso. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef _PLATFORM_INTERNAL_H +#define _PLATFORM_INTERNAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BH_PLATFORM_COSMOPOLITAN +#define BH_PLATFORM_COSMOPOLITAN +#endif + +/* Stack size of applet threads's native part. */ +#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) + +/* Default thread priority */ +#define BH_THREAD_DEFAULT_PRIORITY 0 + +typedef pthread_t korp_tid; +typedef pthread_mutex_t korp_mutex; +typedef pthread_cond_t korp_cond; +typedef pthread_t korp_thread; +typedef sem_t korp_sem; + +#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define os_thread_local_attribute __thread + +#define bh_socket_t int + +#if WASM_DISABLE_WRITE_GS_BASE == 0 +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) +#define os_writegsbase(base_addr) \ + do { \ + uint64 __gs_value = (uint64)(uintptr_t)base_addr; \ + asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \ + } while (0) +#if 0 +/* _writegsbase_u64 also works, but need to add -mfsgsbase flag for gcc */ +#include +#define os_writegsbase(base_addr) \ + _writegsbase_u64(((uint64)(uintptr_t)base_addr)) +#endif +#endif +#endif + +#if WASM_DISABLE_HW_BOUND_CHECK == 0 +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ + || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \ + || defined(BUILD_TARGET_RISCV64_LP64) + +#include + +#define OS_ENABLE_HW_BOUND_CHECK + +typedef jmp_buf korp_jmpbuf; + +#define os_setjmp setjmp +#define os_longjmp longjmp +#define os_alloca alloca + +#define os_getpagesize getpagesize + +typedef void (*os_signal_handler)(void *sig_addr); + +int +os_thread_signal_init(os_signal_handler handler); + +void +os_thread_signal_destroy(); + +bool +os_thread_signal_inited(); + +void +os_signal_unmask(); + +void +os_sigreturn(); +#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */ +#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */ + +#ifdef __cplusplus +} +#endif + +#endif /* end of _PLATFORM_INTERNAL_H */ diff --git a/core/shared/platform/cosmopolitan/shared_platform.cmake b/core/shared/platform/cosmopolitan/shared_platform.cmake new file mode 100644 index 000000000..929ecb9e4 --- /dev/null +++ b/core/shared/platform/cosmopolitan/shared_platform.cmake @@ -0,0 +1,19 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# Copyright (C) 2023 Dylibso. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR}) + +add_definitions(-DBH_PLATFORM_COSMOPOLITAN) + +include_directories(${PLATFORM_SHARED_DIR}) +include_directories(${PLATFORM_SHARED_DIR}/../include) + +include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake) + +file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c) + +set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE}) + +file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h) +LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header}) diff --git a/product-mini/README.md b/product-mini/README.md index 92f8183e0..22acfeaf4 100644 --- a/product-mini/README.md +++ b/product-mini/README.md @@ -443,3 +443,23 @@ make aos make ``` download the binary to developerkit board, check the output from serial port + +## Cosmopolitan Libc +Currently, only x86_64 architecture with interpreter modes is supported. + +Clone the Cosmopolitan Libc. Setup `cosmocc` as described in [Getting Started](https://github.com/jart/cosmopolitan/#getting-started) being sure to get it into `PATH`. + +Build iwasm +``` Bash +export CC=cosmocc +export CXX=cosmoc++ +rm -rf build +mkdir build +cmake -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=1 -B build +cmake --build build -j +``` + +Run like +``` Bash +./build/iwasm.com +``` diff --git a/product-mini/platforms/cosmopolitan/CMakeLists.txt b/product-mini/platforms/cosmopolitan/CMakeLists.txt new file mode 100644 index 000000000..8533ea68c --- /dev/null +++ b/product-mini/platforms/cosmopolitan/CMakeLists.txt @@ -0,0 +1,175 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# Copyright (C) 2023 Dylibso. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 3.14) + +include(CheckPIESupported) + +project (iwasm) + +set (CMAKE_VERBOSE_MAKEFILE OFF) + +set (WAMR_BUILD_PLATFORM "cosmopolitan") + +set(CMAKE_EXECUTABLE_SUFFIX ".com") + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +set (CMAKE_C_STANDARD 99) +set (CMAKE_CXX_STANDARD 17) + +# Set WAMR_BUILD_TARGET, currently values supported: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + else () + message(SEND_ERROR "Unsupported build target platform!") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + +if (NOT DEFINED WAMR_BUILD_INTERP) + # Enable Interpreter by default + set (WAMR_BUILD_INTERP 1) +endif () + +if (NOT DEFINED WAMR_BUILD_AOT) + # Enable AOT by default. + set (WAMR_BUILD_AOT 1) +endif () + +if (NOT DEFINED WAMR_BUILD_JIT) + # Disable JIT by default. + set (WAMR_BUILD_JIT 0) +endif () + +if (NOT DEFINED WAMR_BUILD_FAST_JIT) + # Disable Fast JIT by default + set (WAMR_BUILD_FAST_JIT 0) +endif () + +if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) + # Enable libc builtin support by default + set (WAMR_BUILD_LIBC_BUILTIN 1) +endif () + +if (NOT DEFINED WAMR_BUILD_LIBC_WASI) + # Enable libc wasi support by default + set (WAMR_BUILD_LIBC_WASI 1) +endif () + +if (NOT DEFINED WAMR_BUILD_FAST_INTERP) + # Enable fast interpreter + set (WAMR_BUILD_FAST_INTERP 1) +endif () + +if (NOT DEFINED WAMR_BUILD_MULTI_MODULE) + # Disable multiple modules by default + set (WAMR_BUILD_MULTI_MODULE 0) +endif () + +if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD) + # Disable pthread library by default + set (WAMR_BUILD_LIB_PTHREAD 0) +endif () + +if (NOT DEFINED WAMR_BUILD_LIB_WASI_THREADS) + # Disable wasi threads library by default + set (WAMR_BUILD_LIB_WASI_THREADS 0) +endif() + + +if (NOT DEFINED WAMR_BUILD_MINI_LOADER) + # Disable wasm mini loader by default + set (WAMR_BUILD_MINI_LOADER 0) +endif () + +if (NOT DEFINED WAMR_BUILD_SIMD) + # Enable SIMD by default + set (WAMR_BUILD_SIMD 1) +endif () + +if (NOT DEFINED WAMR_BUILD_REF_TYPES) + # Disable reference types by default + set (WAMR_BUILD_REF_TYPES 0) +endif () + +if (NOT DEFINED WAMR_BUILD_DEBUG_INTERP) + # Disable Debug feature by default + set (WAMR_BUILD_DEBUG_INTERP 0) +endif () + +if (WAMR_BUILD_DEBUG_INTERP EQUAL 1) + set (WAMR_BUILD_FAST_INTERP 0) + set (WAMR_BUILD_MINI_LOADER 0) + set (WAMR_BUILD_SIMD 0) +endif () + +set (WAMR_DISABLE_STACK_HW_BOUND_CHECK 1) +set (WAMR_BUILD_AOT 0) +set (WAMR_DISABLE_WRITE_GS_BASE 1) + +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) + +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) + +check_pie_supported() +add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) +set_target_properties (vmlib PROPERTIES POSITION_INDEPENDENT_CODE ON) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wshadow") +# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion") + +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wno-unused") + +if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mindirect-branch-register") + # UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub + endif () +endif () + +# The following flags are to enhance security, but it may impact performance, +# we disable them by default. +#if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") +# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftrapv -D_FORTIFY_SOURCE=2") +#endif () +#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4") +#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now") + +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +add_executable (iwasm main.c ${UNCOMMON_SHARED_SOURCE}) + +set_target_properties (iwasm PROPERTIES POSITION_INDEPENDENT_CODE ON) + +install (TARGETS iwasm DESTINATION bin) + +target_link_libraries (iwasm vmlib ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} ${WASI_NN_LIBS} -lm -ldl -lpthread) + +add_library (libiwasm STATIC ${WAMR_RUNTIME_LIB_SOURCE}) + +install (TARGETS libiwasm DESTINATION lib) + +set_target_properties (libiwasm PROPERTIES OUTPUT_NAME iwasm) + +target_link_libraries (libiwasm ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} ${WASI_NN_LIBS} -lm -ldl -lpthread) diff --git a/product-mini/platforms/cosmopolitan/build_cosmocc.sh b/product-mini/platforms/cosmopolitan/build_cosmocc.sh new file mode 100755 index 000000000..b2ce15d33 --- /dev/null +++ b/product-mini/platforms/cosmopolitan/build_cosmocc.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Copyright (C) 2023 Dylibso. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +export CC=cosmocc +export CXX=cosmoc++ +rm -rf build +mkdir build +cmake -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=1 -B build +cmake --build build -j diff --git a/product-mini/platforms/cosmopolitan/main.c b/product-mini/platforms/cosmopolitan/main.c new file mode 100644 index 000000000..8f0e84a97 --- /dev/null +++ b/product-mini/platforms/cosmopolitan/main.c @@ -0,0 +1,6 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "../posix/main.c" diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 1caaa89b0..1966de5e0 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -31,6 +31,7 @@ function help() echo "-Q enable qemu" echo "-F set the firmware path used by qemu" echo "-C enable code coverage collect" + echo "-j set the platform to test" } OPT_PARSED="" @@ -58,7 +59,7 @@ QEMU_FIRMWARE="" # prod/testsuite-all branch WASI_TESTSUITE_COMMIT="cf64229727f71043d5849e73934e249e12cb9e06" -while getopts ":s:cabgvt:m:MCpSXxwPGQF:" opt +while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:" opt do OPT_PARSED="TRUE" case $opt in @@ -160,6 +161,10 @@ do echo "QEMU firmware" ${OPTARG} QEMU_FIRMWARE=${OPTARG} ;; + j) + echo "test platform " ${OPTARG} + PLATFORM=${OPTARG} + ;; ?) help exit 1;; @@ -383,6 +388,8 @@ function spec_test() local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm if [ ! -f ${WAT2WASM} ]; then case ${PLATFORM} in + cosmopolitan) + ;& linux) WABT_PLATFORM=ubuntu ;; @@ -656,6 +663,20 @@ function build_iwasm_with_cfg() echo -e "build iwasm failed" exit 1 fi + + if [[ ${PLATFORM} == "cosmopolitan" ]]; then + # convert from APE to ELF so it can be ran easier + # HACK: link to linux so tests work when platform is detected by uname + cp iwasm.com iwasm \ + && ./iwasm --assimilate \ + && rm -rf ../../linux/build \ + && mkdir ../../linux/build \ + && ln -s ../../cosmopolitan/build/iwasm ../../linux/build/iwasm + if [ "$?" != 0 ];then + echo -e "build iwasm failed (cosmopolitan)" + exit 1 + fi + fi } function build_wamrc() From 74acfd964ee6a0b93621f93d9de279be69c56c7d Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:12:08 +0100 Subject: [PATCH 53/58] Run rust tests from wasi-testsuite (#2484) --- tests/wamr-test-suites/test_wamr.sh | 2 +- tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 1966de5e0..a08031331 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -57,7 +57,7 @@ PARALLELISM=0 ENABLE_QEMU=0 QEMU_FIRMWARE="" # prod/testsuite-all branch -WASI_TESTSUITE_COMMIT="cf64229727f71043d5849e73934e249e12cb9e06" +WASI_TESTSUITE_COMMIT="ee807fc551978490bf1c277059aabfa1e589a6c2" while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:" opt do diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index c4b27390e..b8e3ddfec 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -20,6 +20,7 @@ readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/b readonly IWASM_CMD_STRESS="${IWASM_CMD} --max-threads=12" readonly WAMRC_CMD="${WORK_DIR}/../../../../wamr-compiler/build/wamrc" readonly C_TESTS="tests/c/testsuite/" +readonly RUST_TESTS="tests/rust/testsuite/" readonly ASSEMBLYSCRIPT_TESTS="tests/assemblyscript/testsuite/" readonly THREAD_PROPOSAL_TESTS="tests/proposals/wasi-threads/" readonly THREAD_INTERNAL_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/test/" @@ -70,6 +71,7 @@ if [[ $MODE != "aot" ]];then -r adapters/wasm-micro-runtime.py \ -t \ ${C_TESTS} \ + ${RUST_TESTS} \ ${ASSEMBLYSCRIPT_TESTS} \ ${THREAD_PROPOSAL_TESTS} \ ${THREAD_INTERNAL_TESTS} \ From 1ef7c1c83d101b9f9fd6f81884929fa96b512d40 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Sat, 7 Oct 2023 15:50:29 +0800 Subject: [PATCH 54/58] spec-test-script: Fix NaN comparision between v128 values (#2605) --- .../wamr-test-suites/spec-test-script/all.py | 4 +-- .../spec-test-script/runtest.py | 29 +++++++------------ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/tests/wamr-test-suites/spec-test-script/all.py b/tests/wamr-test-suites/spec-test-script/all.py index 44b0a14bd..12ac005bb 100644 --- a/tests/wamr-test-suites/spec-test-script/all.py +++ b/tests/wamr-test-suites/spec-test-script/all.py @@ -199,7 +199,8 @@ def test_case( case_path = pathlib.Path(case_path).resolve() case_name = case_path.stem - CMD.append(case_path) + CMD.append(str(case_path)) + # print(f"============> use {' '.join(CMD)}") print(f"============> run {case_name} ", end="") with subprocess.Popen( CMD, @@ -481,7 +482,6 @@ def main(): ) options = parser.parse_args() - print(options) if not preflight_check(options.aot_flag): return False diff --git a/tests/wamr-test-suites/spec-test-script/runtest.py b/tests/wamr-test-suites/spec-test-script/runtest.py index 633a57313..566a165f3 100755 --- a/tests/wamr-test-suites/spec-test-script/runtest.py +++ b/tests/wamr-test-suites/spec-test-script/runtest.py @@ -400,7 +400,7 @@ def cast_v128_to_i64x2(numbers, type, lane_type): assert(packed) unpacked = struct.unpack("Q Q", packed) - return unpacked, "[{} {}]:{}:v128".format(unpacked[0], unpacked[1], lane_type) + return unpacked, f"[{unpacked[0]:#x} {unpacked[1]:#x}]:{lane_type}:v128" def parse_simple_const_w_type(number, type): @@ -412,13 +412,7 @@ def parse_simple_const_w_type(number, type): else "-0x{:x}:{}".format(0 - number, type) elif type in ["f32", "f64"]: if "nan:" in number: - # TODO: how to handle this correctly - if "nan:canonical" in number: - return float.fromhex("0x200000"), "nan:{}".format(type) - elif "nan:arithmetic" in number: - return float.fromhex("-0x200000"), "nan:{}".format(type) - else: - return float('nan'), "nan:{}".format(type) + return float('nan'), "nan:{}".format(type) else: number = float.fromhex(number) if '0x' in number else float(number) return number, "{:.7g}:{}".format(number, type) @@ -542,9 +536,6 @@ def vector_value_comparison(out, expected): if out_type != expected_type: return False - if out_val == expected_val: - return True - out_val = out_val.split(" ") expected_val = expected_val.split(" ") @@ -568,12 +559,14 @@ def vector_value_comparison(out, expected): out_is_nan = [math.isnan(o) for o in out_unpacked] expected_is_nan = [math.isnan(e) for e in expected_unpacked] - if out_is_nan and expected_is_nan: - return True; + if any(out_is_nan): + nan_comparision = [o == e for o, e in zip(out_is_nan, expected_is_nan)] + if all(nan_comparision): + print(f"Pass NaN comparision") + return True - # print("compare {} and {}".format(out_unpacked, expected_unpacked)) + # print(f"compare {out_unpacked} and {expected_unpacked}") result = [o == e for o, e in zip(out_unpacked, expected_unpacked)] - if not all(result): result = [ "{:.7g}".format(o) == "{:.7g}".format(e) @@ -778,7 +771,7 @@ def test_assert_return(r, opts, form): numbers, _ = cast_v128_to_i64x2(splitted[2:], 'v128', splitted[1]) assert(len(numbers) == 2), "has to reform arguments into i64x2" - args.append("{}\{}".format(numbers[0], numbers[1])) + args.append(f"{numbers[0]:#x}\{numbers[1]:#x}") elif "ref.null" == splitted[0]: args.append("null") elif "ref.extern" == splitted[0]: @@ -1129,7 +1122,7 @@ def test_assert_with_exception(form, wast_tempfile, wasm_tempfile, aot_tempfile, if __name__ == "__main__": opts = parser.parse_args(sys.argv[1:]) - print('Input param :',opts) + # print('Input param :',opts) if opts.aot: test_aot = True # default x86_64 @@ -1152,7 +1145,7 @@ if __name__ == "__main__": ret_code = 0 try: - log("################################################") + log("\n################################################") log("### Testing %s" % opts.test_file.name) log("################################################") forms = read_forms(opts.test_file.read()) From 3668093053bc57f2c6e08c1a637b828b3792facf Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Sat, 7 Oct 2023 08:05:10 +0000 Subject: [PATCH 55/58] Enable AOT usage on M1 mac (#2618) --- core/iwasm/aot/aot_loader.c | 3 +++ core/iwasm/aot/arch/aot_reloc_aarch64.c | 5 +++++ core/shared/platform/alios/alios_platform.c | 4 ++++ core/shared/platform/alios/alios_thread.c | 4 ++++ core/shared/platform/common/posix/posix_memmap.c | 16 ++++++++++++++++ core/shared/platform/common/posix/posix_thread.c | 8 ++++++++ core/shared/platform/esp-idf/espidf_memmap.c | 4 ++++ core/shared/platform/esp-idf/espidf_platform.c | 4 ++++ .../platform/include/platform_api_vmcore.h | 13 +++++++++++++ core/shared/platform/linux-sgx/sgx_platform.c | 4 ++++ core/shared/platform/linux-sgx/sgx_thread.c | 4 ++++ core/shared/platform/nuttx/nuttx_platform.c | 4 ++++ core/shared/platform/riot/riot_platform.c | 4 ++++ core/shared/platform/riot/riot_thread.c | 4 ++++ core/shared/platform/rt-thread/rtt_platform.c | 8 ++++++++ core/shared/platform/windows/platform_init.c | 4 ++++ core/shared/platform/windows/win_thread.c | 4 ++++ core/shared/platform/zephyr/zephyr_platform.c | 4 ++++ core/shared/platform/zephyr/zephyr_thread.c | 4 ++++ 19 files changed, 105 insertions(+) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index b5fa33c0c..6e2fc3248 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -3232,10 +3232,13 @@ aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf, if (!module) return NULL; + os_thread_jit_write_protect_np(false); /* Make memory writable */ if (!load(buf, size, module, error_buf, error_buf_size)) { aot_unload(module); return NULL; } + os_thread_jit_write_protect_np(true); /* Make memory executable */ + os_icache_flush(module->code, module->code_size); LOG_VERBOSE("Load module success.\n"); return module; diff --git a/core/iwasm/aot/arch/aot_reloc_aarch64.c b/core/iwasm/aot/arch/aot_reloc_aarch64.c index 4c46eaa00..b4bb6024a 100644 --- a/core/iwasm/aot/arch/aot_reloc_aarch64.c +++ b/core/iwasm/aot/arch/aot_reloc_aarch64.c @@ -53,7 +53,12 @@ get_target_symbol_map(uint32 *sym_num) return target_sym_map; } +#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__) +#define BUILD_TARGET_AARCH64_DEFAULT "arm64" +#else #define BUILD_TARGET_AARCH64_DEFAULT "aarch64v8" +#endif + void get_current_target(char *target_buf, uint32 target_buf_size) { diff --git a/core/shared/platform/alios/alios_platform.c b/core/shared/platform/alios/alios_platform.c index c9f5f17e6..60393ae52 100644 --- a/core/shared/platform/alios/alios_platform.c +++ b/core/shared/platform/alios/alios_platform.c @@ -69,3 +69,7 @@ os_mprotect(void *addr, size_t size, int prot) void os_dcache_flush() {} + +void +os_icache_flush(void *start, size_t len) +{} diff --git a/core/shared/platform/alios/alios_thread.c b/core/shared/platform/alios/alios_thread.c index 0efd2f394..9fe927db0 100644 --- a/core/shared/platform/alios/alios_thread.c +++ b/core/shared/platform/alios/alios_thread.c @@ -359,3 +359,7 @@ os_thread_get_stack_boundary() /* TODO: get alios stack boundary */ return NULL; } + +void +os_thread_jit_write_protect_np(bool enabled) +{} \ No newline at end of file diff --git a/core/shared/platform/common/posix/posix_memmap.c b/core/shared/platform/common/posix/posix_memmap.c index 2dfbee453..5d33dcc81 100644 --- a/core/shared/platform/common/posix/posix_memmap.c +++ b/core/shared/platform/common/posix/posix_memmap.c @@ -5,6 +5,10 @@ #include "platform_api_vmcore.h" +#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__) +#include +#endif + #ifndef BH_ENABLE_TRACE_MMAP #define BH_ENABLE_TRACE_MMAP 0 #endif @@ -36,7 +40,11 @@ void * os_mmap(void *hint, size_t size, int prot, int flags) { int map_prot = PROT_NONE; +#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__) + int map_flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT; +#else int map_flags = MAP_ANONYMOUS | MAP_PRIVATE; +#endif uint64 request_size, page_size; uint8 *addr = MAP_FAILED; uint32 i; @@ -251,3 +259,11 @@ os_mprotect(void *addr, size_t size, int prot) void os_dcache_flush(void) {} + +void +os_icache_flush(void *start, size_t len) +{ +#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__) + sys_icache_invalidate(start, len); +#endif +} \ No newline at end of file diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index a7bdc6d10..498f5f5a2 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -418,6 +418,14 @@ os_thread_get_stack_boundary() return addr; } +void +os_thread_jit_write_protect_np(bool enabled) +{ +#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__) + pthread_jit_write_protect_np(enabled); +#endif +} + #ifdef OS_ENABLE_HW_BOUND_CHECK #define SIG_ALT_STACK_SIZE (32 * 1024) diff --git a/core/shared/platform/esp-idf/espidf_memmap.c b/core/shared/platform/esp-idf/espidf_memmap.c index 0a1fd4fe4..ce94a9549 100644 --- a/core/shared/platform/esp-idf/espidf_memmap.c +++ b/core/shared/platform/esp-idf/espidf_memmap.c @@ -100,6 +100,10 @@ void #endif } +void +os_icache_flush(void *start, size_t len) +{} + #if (WASM_MEM_DUAL_BUS_MIRROR != 0) void * os_get_dbus_mirror(void *ibus) diff --git a/core/shared/platform/esp-idf/espidf_platform.c b/core/shared/platform/esp-idf/espidf_platform.c index 35b893d81..bbc18f69b 100644 --- a/core/shared/platform/esp-idf/espidf_platform.c +++ b/core/shared/platform/esp-idf/espidf_platform.c @@ -53,6 +53,10 @@ os_thread_get_stack_boundary(void) #endif } +void +os_thread_jit_write_protect_np(bool enabled) +{} + int os_usleep(uint32 usec) { diff --git a/core/shared/platform/include/platform_api_vmcore.h b/core/shared/platform/include/platform_api_vmcore.h index 15fc1d387..c803c12e4 100644 --- a/core/shared/platform/include/platform_api_vmcore.h +++ b/core/shared/platform/include/platform_api_vmcore.h @@ -81,6 +81,13 @@ os_self_thread(void); uint8 * os_thread_get_stack_boundary(void); +/** + * Set whether the MAP_JIT region write protection is enabled for this thread. + * Pass true to make the region executable, false to make it writable. + */ +void +os_thread_jit_write_protect_np(bool enabled); + /** ************** mutext APIs *********** * vmcore: Not required until pthread is supported by runtime @@ -143,6 +150,12 @@ os_get_dbus_mirror(void *ibus); void os_dcache_flush(void); +/** + * Flush instruction cache. + */ +void +os_icache_flush(void *start, size_t len); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/linux-sgx/sgx_platform.c b/core/shared/platform/linux-sgx/sgx_platform.c index b40eaf79c..1a90af4c6 100644 --- a/core/shared/platform/linux-sgx/sgx_platform.c +++ b/core/shared/platform/linux-sgx/sgx_platform.c @@ -195,3 +195,7 @@ os_mprotect(void *addr, size_t size, int prot) void os_dcache_flush(void) {} + +void +os_icache_flush(void *start, size_t len) +{} \ No newline at end of file diff --git a/core/shared/platform/linux-sgx/sgx_thread.c b/core/shared/platform/linux-sgx/sgx_thread.c index 1cb2f5d09..d9412927b 100644 --- a/core/shared/platform/linux-sgx/sgx_thread.c +++ b/core/shared/platform/linux-sgx/sgx_thread.c @@ -210,3 +210,7 @@ os_thread_get_stack_boundary() /* TODO: get sgx stack boundary */ return NULL; } + +void +os_thread_jit_write_protect_np(bool enabled) +{} \ No newline at end of file diff --git a/core/shared/platform/nuttx/nuttx_platform.c b/core/shared/platform/nuttx/nuttx_platform.c index 0bd1f6808..92c17ed48 100644 --- a/core/shared/platform/nuttx/nuttx_platform.c +++ b/core/shared/platform/nuttx/nuttx_platform.c @@ -144,6 +144,10 @@ os_dcache_flush() bus_sync(); } +void +os_icache_flush(void *start, size_t len) +{} + #if (WASM_MEM_DUAL_BUS_MIRROR != 0) void * os_get_dbus_mirror(void *ibus) diff --git a/core/shared/platform/riot/riot_platform.c b/core/shared/platform/riot/riot_platform.c index a0c38e8c9..6fd6617b4 100644 --- a/core/shared/platform/riot/riot_platform.c +++ b/core/shared/platform/riot/riot_platform.c @@ -79,3 +79,7 @@ os_dcache_flush(void) irq_unlock(key); #endif } + +void +os_icache_flush(void *start, size_t len) +{} \ No newline at end of file diff --git a/core/shared/platform/riot/riot_thread.c b/core/shared/platform/riot/riot_thread.c index 0ebcf30e0..a9062bfec 100644 --- a/core/shared/platform/riot/riot_thread.c +++ b/core/shared/platform/riot/riot_thread.c @@ -430,3 +430,7 @@ os_thread_get_stack_boundary() return NULL; #endif } + +void +os_thread_jit_write_protect_np(bool enabled) +{} \ No newline at end of file diff --git a/core/shared/platform/rt-thread/rtt_platform.c b/core/shared/platform/rt-thread/rtt_platform.c index 4685e1ea3..6dc719f01 100644 --- a/core/shared/platform/rt-thread/rtt_platform.c +++ b/core/shared/platform/rt-thread/rtt_platform.c @@ -140,6 +140,10 @@ os_thread_get_stack_boundary(void) return tid->stack_addr; } +void +os_thread_jit_write_protect_np(bool enabled) +{} + int os_mutex_init(korp_mutex *mutex) { @@ -207,3 +211,7 @@ os_mprotect(void *addr, size_t size, int prot) void os_dcache_flush(void) {} + +void +os_icache_flush(void *start, size_t len) +{} \ No newline at end of file diff --git a/core/shared/platform/windows/platform_init.c b/core/shared/platform/windows/platform_init.c index db5885387..96bcf9ab1 100644 --- a/core/shared/platform/windows/platform_init.c +++ b/core/shared/platform/windows/platform_init.c @@ -73,3 +73,7 @@ os_getpagesize() void os_dcache_flush(void) {} + +void +os_icache_flush(void *start, size_t len) +{} \ No newline at end of file diff --git a/core/shared/platform/windows/win_thread.c b/core/shared/platform/windows/win_thread.c index 09cf0c63f..abc36f2fc 100644 --- a/core/shared/platform/windows/win_thread.c +++ b/core/shared/platform/windows/win_thread.c @@ -712,6 +712,10 @@ os_thread_get_stack_boundary() return thread_stack_boundary; } +void +os_thread_jit_write_protect_np(bool enabled) +{} + #ifdef OS_ENABLE_HW_BOUND_CHECK static os_thread_local_attribute bool thread_signal_inited = false; diff --git a/core/shared/platform/zephyr/zephyr_platform.c b/core/shared/platform/zephyr/zephyr_platform.c index b4f2e5ec7..715be8b94 100644 --- a/core/shared/platform/zephyr/zephyr_platform.c +++ b/core/shared/platform/zephyr/zephyr_platform.c @@ -214,6 +214,10 @@ os_dcache_flush() #endif } +void +os_icache_flush(void *start, size_t len) +{} + void set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func, exec_mem_free_func_t free_func) diff --git a/core/shared/platform/zephyr/zephyr_thread.c b/core/shared/platform/zephyr/zephyr_thread.c index 1ee2c5cef..105d53993 100644 --- a/core/shared/platform/zephyr/zephyr_thread.c +++ b/core/shared/platform/zephyr/zephyr_thread.c @@ -574,3 +574,7 @@ os_thread_get_stack_boundary() return NULL; #endif } + +void +os_thread_jit_write_protect_np(bool enabled) +{} \ No newline at end of file From b115b7baac4d7c1a2f4d92278ad18cd53d265ff1 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Sat, 7 Oct 2023 12:55:14 +0100 Subject: [PATCH 56/58] Fix compilation of shift opcodes on x86_64 and i386 architectures (#2619) This change fixes the case where the right parameter of shift operator is negative, specifically, when both parameters of shift opcode are constants. --- .../compilation_on_android_ubuntu.yml | 7 +- core/iwasm/compilation/aot_emit_numberic.c | 18 ++- tests/wamr-compiler/.gitignore | 2 + tests/wamr-compiler/README.md | 3 + .../test_shift_negative_constants.wat | 43 +++++++ tests/wamr-test-suites/test_wamr.sh | 115 +++++++++++------- .../run_wamr_compiler_tests.sh | 22 ++++ 7 files changed, 159 insertions(+), 51 deletions(-) create mode 100644 tests/wamr-compiler/.gitignore create mode 100644 tests/wamr-compiler/README.md create mode 100644 tests/wamr-compiler/test_shift_negative_constants.wat create mode 100755 tests/wamr-test-suites/wamr-compiler-test-script/run_wamr_compiler_tests.sh diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 3c5b4e35e..3d6e44c6b 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -65,6 +65,7 @@ env: THREADS_TEST_OPTIONS: "-s spec -b -p -P" X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P" WASI_TEST_OPTIONS: "-s wasi_certification -w" + WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -b -P" jobs: build_llvm_libraries_on_ubuntu_2204: @@ -333,7 +334,7 @@ jobs: build_iwasm, build_llvm_libraries_on_ubuntu_2204, build_wamrc, - ] + ] runs-on: ${{ matrix.os }} strategy: matrix: @@ -482,6 +483,10 @@ jobs: - os: ubuntu-22.04 llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} ubuntu_version: "22.04" + - os: ubuntu-22.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} + running_mode: aot + test_option: $WAMR_COMPILER_TEST_OPTIONS exclude: # uncompatiable modes and features # classic-interp and fast-interp don't support simd diff --git a/core/iwasm/compilation/aot_emit_numberic.c b/core/iwasm/compilation/aot_emit_numberic.c index f540dbe04..bda64f831 100644 --- a/core/iwasm/compilation/aot_emit_numberic.c +++ b/core/iwasm/compilation/aot_emit_numberic.c @@ -171,6 +171,15 @@ right = shift_count_mask; \ } while (0) +static bool +is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left, + LLVMValueRef right) +{ + return (strcmp(comp_ctx->target_arch, "x86_64") != 0 + && strcmp(comp_ctx->target_arch, "i386") != 0) + || (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right)); +} + /* Call llvm constrained floating-point intrinsic */ static LLVMValueRef call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx, @@ -728,8 +737,7 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right, { LLVMValueRef res; - if (strcmp(comp_ctx->target_arch, "x86_64") != 0 - && strcmp(comp_ctx->target_arch, "i386") != 0) + if (is_shift_count_mask_needed(comp_ctx, left, right)) SHIFT_COUNT_MASK; /* Build shl */ @@ -744,8 +752,7 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left, { LLVMValueRef res; - if (strcmp(comp_ctx->target_arch, "x86_64") != 0 - && strcmp(comp_ctx->target_arch, "i386") != 0) + if (is_shift_count_mask_needed(comp_ctx, left, right)) SHIFT_COUNT_MASK; /* Build shl */ @@ -760,8 +767,7 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left, { LLVMValueRef res; - if (strcmp(comp_ctx->target_arch, "x86_64") != 0 - && strcmp(comp_ctx->target_arch, "i386") != 0) + if (is_shift_count_mask_needed(comp_ctx, left, right)) SHIFT_COUNT_MASK; /* Build shl */ diff --git a/tests/wamr-compiler/.gitignore b/tests/wamr-compiler/.gitignore new file mode 100644 index 000000000..5425c41bd --- /dev/null +++ b/tests/wamr-compiler/.gitignore @@ -0,0 +1,2 @@ +*.aot +*.wasm \ No newline at end of file diff --git a/tests/wamr-compiler/README.md b/tests/wamr-compiler/README.md new file mode 100644 index 000000000..d48ea9827 --- /dev/null +++ b/tests/wamr-compiler/README.md @@ -0,0 +1,3 @@ +# WAMR test benchmarks + +This folder contains tests for WAMR AOT compiler and its generated code. diff --git a/tests/wamr-compiler/test_shift_negative_constants.wat b/tests/wamr-compiler/test_shift_negative_constants.wat new file mode 100644 index 000000000..030cc8983 --- /dev/null +++ b/tests/wamr-compiler/test_shift_negative_constants.wat @@ -0,0 +1,43 @@ +;; Copyright (C) 2023 Amazon Inc. All rights reserved. +;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +;; +;; Those tests verify if passing constant negative value +;; as a right parameter of the shift operator (along +;; with a constant value of the left operator) causes +;; any problems. See: https://github.com/bytecodealliance/wasm-micro-runtime/pull/2619 +(module + (memory (export "memory") 1 1) + (func $assert_eq (param i32 i32) + (i32.ne (local.get 0) (local.get 1)) + if + unreachable + end + ) + + (func $i32_shr_u + (call $assert_eq + (i32.shr_u (i32.const -1) (i32.const -5)) + (i32.const 31) + ) + ) + + (func $i32_shr_s + (call $assert_eq + (i32.shr_u (i32.const 32) (i32.const -30)) + (i32.const 8) + ) + ) + + (func $i32_shl + (call $assert_eq + (i32.shl (i32.const -1) (i32.const -30)) + (i32.const -4) + ) + ) + + (func (export "_start") + call $i32_shr_u + call $i32_shr_s + call $i32_shl + ) +) diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index a08031331..81844f0e7 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -14,7 +14,7 @@ function help() { echo "test_wamr.sh [options]" echo "-c clean previous test results, not start test" - echo "-s {suite_name} test only one suite (spec|wasi_certification)" + echo "-s {suite_name} test only one suite (spec|wasi_certification|wamr_compiler)" echo "-m set compile target of iwasm(x86_64|x86_32|armv7_vfp|thumbv7_vfp|riscv64_lp64d|riscv64_lp64|aarch64)" echo "-t set compile type of iwasm(classic-interp|fast-interp|jit|aot|fast-jit|multi-tier-jit)" echo "-M enable multi module feature" @@ -309,6 +309,53 @@ function sightglass_test() echo "Finish sightglass benchmark tests" } +function setup_wabt() +{ + if [ ${WABT_BINARY_RELEASE} == "YES" ]; then + echo "download a binary release and install" + local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm + if [ ! -f ${WAT2WASM} ]; then + case ${PLATFORM} in + cosmopolitan) + ;& + linux) + WABT_PLATFORM=ubuntu + ;; + darwin) + WABT_PLATFORM=macos + ;; + *) + echo "wabt platform for ${PLATFORM} in unknown" + exit 1 + ;; + esac + if [ ! -f /tmp/wabt-1.0.31-${WABT_PLATFORM}.tar.gz ]; then + wget \ + https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-${WABT_PLATFORM}.tar.gz \ + -P /tmp + fi + + cd /tmp \ + && tar zxf wabt-1.0.31-${WABT_PLATFORM}.tar.gz \ + && mkdir -p ${WORK_DIR}/wabt/out/gcc/Release/ \ + && install wabt-1.0.31/bin/wa* ${WORK_DIR}/wabt/out/gcc/Release/ \ + && cd - + fi + else + echo "download source code and compile and install" + if [ ! -d "wabt" ];then + echo "wabt not exist, clone it from github" + git clone --recursive https://github.com/WebAssembly/wabt + fi + echo "upate wabt" + cd wabt + git pull + git reset --hard origin/main + cd .. + make -C wabt gcc-release -j 4 + fi +} + # TODO: with iwasm only function spec_test() { @@ -383,49 +430,7 @@ function spec_test() popd echo $(pwd) - if [ ${WABT_BINARY_RELEASE} == "YES" ]; then - echo "download a binary release and install" - local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm - if [ ! -f ${WAT2WASM} ]; then - case ${PLATFORM} in - cosmopolitan) - ;& - linux) - WABT_PLATFORM=ubuntu - ;; - darwin) - WABT_PLATFORM=macos - ;; - *) - echo "wabt platform for ${PLATFORM} in unknown" - exit 1 - ;; - esac - if [ ! -f /tmp/wabt-1.0.31-${WABT_PLATFORM}.tar.gz ]; then - wget \ - https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-${WABT_PLATFORM}.tar.gz \ - -P /tmp - fi - - cd /tmp \ - && tar zxf wabt-1.0.31-${WABT_PLATFORM}.tar.gz \ - && mkdir -p ${WORK_DIR}/wabt/out/gcc/Release/ \ - && install wabt-1.0.31/bin/wa* ${WORK_DIR}/wabt/out/gcc/Release/ \ - && cd - - fi - else - echo "download source code and compile and install" - if [ ! -d "wabt" ];then - echo "wabt not exist, clone it from github" - git clone --recursive https://github.com/WebAssembly/wabt - fi - echo "upate wabt" - cd wabt - git pull - git reset --hard origin/main - cd .. - make -C wabt gcc-release -j 4 - fi + setup_wabt ln -sf ${WORK_DIR}/../spec-test-script/all.py . ln -sf ${WORK_DIR}/../spec-test-script/runtest.py . @@ -513,6 +518,28 @@ function wasi_test() echo "Finish wasi tests" } +function wamr_compiler_test() +{ + if [[ $1 != "aot" ]]; then + echo "WAMR compiler tests only support AOT mode" + exit 1 + fi + + echo "Now start WAMR compiler tests" + setup_wabt + cd ${WORK_DIR}/../wamr-compiler-test-script + ./run_wamr_compiler_tests.sh ${WORK_DIR}/wabt/out/gcc/Release/wat2wasm $WAMRC_CMD $IWASM_CMD \ + | tee -a ${REPORT_DIR}/wamr_compiler_test_report.txt + + ret=${PIPESTATUS[0]} + + if [[ ${ret} -ne 0 ]];then + echo -e "\nWAMR compiler tests FAILED" | tee -a ${REPORT_DIR}/wamr_compiler_test_report.txt + exit 1 + fi + echo -e "\nFinish WAMR compiler tests" | tee -a ${REPORT_DIR}/wamr_compiler_test_report.txt +} + function wasi_certification_test() { echo "Now start wasi certification tests" diff --git a/tests/wamr-test-suites/wamr-compiler-test-script/run_wamr_compiler_tests.sh b/tests/wamr-test-suites/wamr-compiler-test-script/run_wamr_compiler_tests.sh new file mode 100755 index 000000000..19c8030d0 --- /dev/null +++ b/tests/wamr-test-suites/wamr-compiler-test-script/run_wamr_compiler_tests.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright (C) 2023 Amazon Inc. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set -e + +WAT2WASM_CMD=$1 +WAMRC_CMD=$2 +IWASM_CMD=$3 + +for wat_file in ../../wamr-compiler/*.wat; do + wasm_file="${wat_file%.wat}.wasm" + aot_file="${wat_file%.wat}.aot" + + echo "Compiling $wat_file to $wasm_file" + $WAT2WASM_CMD "$wat_file" -o "$wasm_file" + echo "Compiling $wasm_file to $aot_file" + $WAMRC_CMD -o $aot_file $wasm_file + echo "Testing $aot_file" + $IWASM_CMD "$aot_file" +done From 7c22bde8dc8e5aa748f1d65c10f7943087401009 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sun, 8 Oct 2023 08:36:49 +0800 Subject: [PATCH 57/58] CI: Enable testing AOT multi-module feature (#2621) And refine some code pieces. --- .github/workflows/compilation_on_android_ubuntu.yml | 8 ++------ .github/workflows/compilation_on_macos.yml | 4 +--- .github/workflows/compilation_on_sgx.yml | 3 --- .github/workflows/nightly_run.yml | 12 ++++-------- core/iwasm/aot/aot_loader.c | 5 ++++- core/iwasm/common/wasm_runtime_common.c | 6 ++---- .../sandboxed-system-primitives/src/posix.c | 4 ++-- product-mini/platforms/posix/main.c | 4 ++-- product-mini/platforms/windows/main.c | 4 ++-- 9 files changed, 19 insertions(+), 31 deletions(-) diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 3d6e44c6b..6b653b501 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -151,9 +151,7 @@ jobs: exclude: # uncompatiable feature and platform # uncompatiable mode and feature - # MULTI_MODULE only on INTERP mode - - make_options_run_mode: $AOT_BUILD_OPTIONS - make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" + # MULTI_MODULE only on INTERP mode and AOT mode - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS @@ -494,9 +492,7 @@ jobs: test_option: $SIMD_TEST_OPTIONS - running_mode: "fast-interp" test_option: $SIMD_TEST_OPTIONS - # aot and jit don't support multi module - - running_mode: "aot" - test_option: $MULTI_MODULES_TEST_OPTIONS + # llvm jit doesn't support multi module - running_mode: "jit" test_option: $MULTI_MODULES_TEST_OPTIONS # fast-jit doesn't support multi module, simd diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index f06833185..aac16898b 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -133,13 +133,11 @@ jobs: exclude: # uncompatiable feature and platform # uncompatiable mode and feature - # MULTI_MODULE only on INTERP mode + # MULTI_MODULE only on INTERP mode and AOT mode - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" - make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" - - make_options_run_mode: $AOT_BUILD_OPTIONS - make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" # SIMD only on JIT/AOT mode - make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_SIMD=1" diff --git a/.github/workflows/compilation_on_sgx.yml b/.github/workflows/compilation_on_sgx.yml index dd6317067..0d19d83ad 100644 --- a/.github/workflows/compilation_on_sgx.yml +++ b/.github/workflows/compilation_on_sgx.yml @@ -101,9 +101,6 @@ jobs: platform: [linux-sgx] exclude: # uncompatiable mode and feature - # MULTI_MODULE only on INTERP mode - - make_options_run_mode: $AOT_BUILD_OPTIONS - make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" # MINI_LOADER only on INTERP mode - make_options_run_mode: $AOT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index ea79b3f23..bef639792 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -127,9 +127,7 @@ jobs: exclude: # uncompatiable feature and platform # uncompatiable mode and feature - # MULTI_MODULE only on INTERP mode - - make_options_run_mode: $AOT_BUILD_OPTIONS - make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" + # MULTI_MODULE only on INTERP mode and AOT mode - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" - make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS @@ -252,7 +250,7 @@ jobs: exclude: # uncompatiable feature and platform # uncompatiable mode and feature - # MULTI_MODULE only on INTERP mode + # MULTI_MODULE only on INTERP mode and AOT mode - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" # SIMD only on JIT/AOT mode @@ -553,9 +551,7 @@ jobs: test_option: $SIMD_TEST_OPTIONS - running_mode: "fast-interp" test_option: $SIMD_TEST_OPTIONS - # aot and jit don't support multi module - - running_mode: "aot" - test_option: $MULTI_MODULES_TEST_OPTIONS + # llvm jit doesn't support multi module - running_mode: "jit" test_option: $MULTI_MODULES_TEST_OPTIONS # fast-jit doesn't support multi module, simd @@ -660,4 +656,4 @@ jobs: timeout-minutes: 40 if: env.TEST_ON_X86_32 == 'true' run: ./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }} - working-directory: ./tests/wamr-test-suites \ No newline at end of file + working-directory: ./tests/wamr-test-suites diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 6e2fc3248..6575c8aca 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2955,18 +2955,21 @@ create_module(char *error_buf, uint32 error_buf_size) { AOTModule *module = loader_malloc(sizeof(AOTModule), error_buf, error_buf_size); - bh_list_status ret; + if (!module) { return NULL; } + module->module_type = Wasm_Module_AoT; + #if WASM_ENABLE_MULTI_MODULE != 0 module->import_module_list = &module->import_module_list_head; ret = bh_list_init(module->import_module_list); bh_assert(ret == BH_LIST_SUCCESS); #endif (void)ret; + return module; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index d5c40d6e9..8faa5e444 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -126,13 +126,11 @@ runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst, } #if WASM_ENABLE_MULTI_MODULE != 0 -/* - TODO: - Let loader_malloc be a general API both for AOT and WASM. -*/ +/* TODO: Let loader_malloc be a general API both for AOT and WASM. */ #define loader_malloc(size, error_buf, error_buf_size) \ runtime_malloc(size, NULL, error_buf, error_buf_size) + static void set_error_buf_v(const WASMModuleCommon *module, char *error_buf, uint32 error_buf_size, const char *format, ...) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 415a66463..0ba91a7e9 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -710,8 +710,8 @@ fd_object_release(wasm_exec_env_t env, struct fd_object *fo) bool fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in, int out) { - __wasi_filetype_t type; - __wasi_rights_t rights_base, rights_inheriting; + __wasi_filetype_t type = __WASI_FILETYPE_UNKNOWN; + __wasi_rights_t rights_base = 0, rights_inheriting = 0; struct fd_object *fo; __wasi_errno_t error; diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index b7d755410..b27bd8c2e 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -422,7 +422,7 @@ static bool module_reader_callback(package_type_t module_type, const char *module_name, uint8 **p_buffer, uint32 *p_size) { - char *file_format; + char *file_format = NULL; #if WASM_ENABLE_INTERP != 0 if (module_type == Wasm_Module_Bytecode) file_format = ".wasm"; @@ -430,8 +430,8 @@ module_reader_callback(package_type_t module_type, const char *module_name, #if WASM_ENABLE_AOT != 0 if (module_type == Wasm_Module_AoT) file_format = ".aot"; - #endif + bh_assert(file_format); const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + strlen(file_format) + 1; diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 985c9e6c7..f6347919b 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -206,7 +206,7 @@ static bool module_reader_callback(package_type_t module_type, const char *module_name, uint8 **p_buffer, uint32 *p_size) { - char *file_format; + char *file_format = NULL; #if WASM_ENABLE_INTERP != 0 if (module_type == Wasm_Module_Bytecode) file_format = ".wasm"; @@ -214,8 +214,8 @@ module_reader_callback(package_type_t module_type, const char *module_name, #if WASM_ENABLE_AOT != 0 if (module_type == Wasm_Module_AoT) file_format = ".aot"; - #endif + bh_assert(file_format); const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + strlen(file_format) + 1; From 059fbfc2523e8f64e4613d38de681e2365ed76fb Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:17:54 +0800 Subject: [PATCH 58/58] Fix potential issue in aot compiler when translating block opcodes (#2622) The LLVM zext IR may be inserted after the terminator of a basic block when popping the arguments of a wasm block. Change to insert the zext IR before the terminator of the basic block to resolve the issue. Reported in #2620. --- core/iwasm/compilation/aot_emit_control.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 7e710f914..446ca5ea6 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -281,7 +281,7 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx, AOTBlock *block) { uint32 i, param_index; - LLVMValueRef value; + LLVMValueRef value, br_inst; uint64 size; char name[32]; LLVMBasicBlockRef block_curr = CURR_BLOCK(); @@ -329,7 +329,14 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx, } } } - SET_BUILDER_POS(block_curr); + + /* At this point, the branch instruction was already built to jump to + * the new BB, to avoid generating zext instruction from the popped + * operand that would come after branch instruction, we should position + * the builder before the last branch instruction */ + br_inst = LLVMGetLastInstruction(block_curr); + bh_assert(LLVMGetInstructionOpcode(br_inst) == LLVMBr); + LLVMPositionBuilderBefore(comp_ctx->builder, br_inst); /* Pop param values from current block's * value stack and add to param phis.