mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-19 16:11:33 +00:00
Merge branch main into dev/exce_handling
This commit is contained in:
commit
59f4dd4c05
4
.github/workflows/compilation_on_nuttx.yml
vendored
4
.github/workflows/compilation_on_nuttx.yml
vendored
|
@ -94,9 +94,9 @@ jobs:
|
||||||
- name: Install RISC-V Compilers
|
- name: Install RISC-V Compilers
|
||||||
if: contains(matrix.nuttx_board_config, 'risc-v')
|
if: contains(matrix.nuttx_board_config, 'risc-v')
|
||||||
run: |
|
run: |
|
||||||
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
|
curl -L https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v12.3.0-1/xpack-riscv-none-elf-gcc-12.3.0-1-linux-x64.tar.gz > riscv.tar.gz
|
||||||
tar xvf riscv.tar.gz
|
tar xvf riscv.tar.gz
|
||||||
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH
|
echo "$PWD/xpack-riscv-none-elf-gcc-12.3.0-1/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install WASI-SDK
|
- name: Install WASI-SDK
|
||||||
run: |
|
run: |
|
||||||
|
|
61
.github/workflows/compilation_on_windows.yml
vendored
61
.github/workflows/compilation_on_windows.yml
vendored
|
@ -39,6 +39,16 @@ on:
|
||||||
# allow to be triggered manually
|
# allow to be triggered manually
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# For Spec Test
|
||||||
|
DEFAULT_TEST_OPTIONS: "-s spec -b"
|
||||||
|
MULTI_MODULES_TEST_OPTIONS: "-s spec -b -M"
|
||||||
|
THREADS_TEST_OPTIONS: "-s spec -b -p"
|
||||||
|
WASI_TEST_OPTIONS: "-s wasi_certification -w"
|
||||||
|
WASI_TEST_FILTER: ${{ github.workspace }}/product-mini/platforms/windows/wasi_filtered_tests.json
|
||||||
|
# Used when building the WASI socket and thread tests
|
||||||
|
CC: ${{ github.workspace }}/wasi-sdk/bin/clang
|
||||||
|
|
||||||
# Cancel any in-flight jobs for the same PR/branch so there's only one active
|
# Cancel any in-flight jobs for the same PR/branch so there's only one active
|
||||||
# at a time
|
# at a time
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -60,12 +70,14 @@ jobs:
|
||||||
"-DWAMR_BUILD_SIMD=1",
|
"-DWAMR_BUILD_SIMD=1",
|
||||||
"-DWAMR_BUILD_DEBUG_INTERP=1",
|
"-DWAMR_BUILD_DEBUG_INTERP=1",
|
||||||
"-DWAMR_BUILD_LIB_PTHREAD=1",
|
"-DWAMR_BUILD_LIB_PTHREAD=1",
|
||||||
"-DWAMR_BUILD_LIB_WASI_THREADS=1"
|
"-DWAMR_BUILD_LIB_WASI_THREADS=1",
|
||||||
|
"-DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1"
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: clone uvwasi library
|
- name: clone uvwasi library
|
||||||
|
if: ${{ !contains(matrix.build_options, '-DWAMR_BUILD_LIBC_UVWASI=0') }}
|
||||||
run: |
|
run: |
|
||||||
cd core/deps
|
cd core/deps
|
||||||
git clone https://github.com/nodejs/uvwasi.git
|
git clone https://github.com/nodejs/uvwasi.git
|
||||||
|
@ -75,3 +87,50 @@ jobs:
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. ${{ matrix.build_options }}
|
cmake .. ${{ matrix.build_options }}
|
||||||
cmake --build . --config Release --parallel 4
|
cmake --build . --config Release --parallel 4
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: [build]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
running_mode:
|
||||||
|
[
|
||||||
|
"classic-interp",
|
||||||
|
"fast-interp",
|
||||||
|
]
|
||||||
|
test_option:
|
||||||
|
[
|
||||||
|
$DEFAULT_TEST_OPTIONS,
|
||||||
|
$MULTI_MODULES_TEST_OPTIONS,
|
||||||
|
$THREADS_TEST_OPTIONS,
|
||||||
|
$WASI_TEST_OPTIONS,
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: download and install wasi-sdk
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: |
|
||||||
|
curl "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0.m-mingw.tar.gz" -o wasi-sdk.tar.gz -L
|
||||||
|
mkdir wasi-sdk
|
||||||
|
tar -xzf wasi-sdk.tar.gz -C wasi-sdk --strip-components 1
|
||||||
|
|
||||||
|
- name: build socket api tests
|
||||||
|
shell: bash
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: ./build.sh
|
||||||
|
working-directory: ./core/iwasm/libraries/lib-socket/test/
|
||||||
|
|
||||||
|
- name: Build WASI thread tests
|
||||||
|
shell: bash
|
||||||
|
if: matrix.test_option == '$WASI_TEST_OPTIONS'
|
||||||
|
run: ./build.sh
|
||||||
|
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
|
||||||
|
|
||||||
|
- name: run tests
|
||||||
|
shell: bash
|
||||||
|
timeout-minutes: 20
|
||||||
|
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
|
||||||
|
working-directory: ./tests/wamr-test-suites
|
||||||
|
|
40
.github/workflows/nightly_run.yml
vendored
40
.github/workflows/nightly_run.yml
vendored
|
@ -49,10 +49,17 @@ jobs:
|
||||||
with:
|
with:
|
||||||
os: "ubuntu-20.04"
|
os: "ubuntu-20.04"
|
||||||
arch: "X86"
|
arch: "X86"
|
||||||
|
build_llvm_libraries_on_ubuntu_2204:
|
||||||
|
uses: ./.github/workflows/build_llvm_libraries.yml
|
||||||
|
with:
|
||||||
|
os: "ubuntu-22.04"
|
||||||
|
arch: "X86"
|
||||||
|
|
||||||
build_wamrc:
|
build_wamrc:
|
||||||
needs:
|
needs:
|
||||||
[build_llvm_libraries_on_ubuntu_2004]
|
[
|
||||||
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -90,7 +97,9 @@ jobs:
|
||||||
|
|
||||||
build_iwasm:
|
build_iwasm:
|
||||||
needs:
|
needs:
|
||||||
[build_llvm_libraries_on_ubuntu_2004]
|
[
|
||||||
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -497,14 +506,15 @@ jobs:
|
||||||
[
|
[
|
||||||
build_iwasm,
|
build_iwasm,
|
||||||
build_llvm_libraries_on_ubuntu_2004,
|
build_llvm_libraries_on_ubuntu_2004,
|
||||||
|
build_llvm_libraries_on_ubuntu_2204,
|
||||||
build_wamrc,
|
build_wamrc,
|
||||||
]
|
]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04, ubuntu-22.04]
|
||||||
sanitizer: ["", "ubsan", "asan"]
|
sanitizer: ["", "ubsan", "asan", "tsan"]
|
||||||
running_mode:
|
running_mode:
|
||||||
[
|
[
|
||||||
"classic-interp",
|
"classic-interp",
|
||||||
|
@ -530,11 +540,14 @@ jobs:
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
|
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
|
||||||
ubuntu_version: "20.04"
|
ubuntu_version: "20.04"
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
|
||||||
|
ubuntu_version: "22.04"
|
||||||
|
|
||||||
exclude:
|
exclude:
|
||||||
# uncompatiable modes and features
|
# uncompatiable modes and features
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
sanitizer: asan
|
sanitizer: tsan
|
||||||
# asan works only for aot now
|
# asan works only for aot now
|
||||||
- running_mode: "classic-interp"
|
- running_mode: "classic-interp"
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
|
@ -546,6 +559,14 @@ jobs:
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
- running_mode: "multi-tier-jit"
|
- running_mode: "multi-tier-jit"
|
||||||
sanitizer: asan
|
sanitizer: asan
|
||||||
|
- running_mode: "classic-interp"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "jit"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "fast-jit"
|
||||||
|
sanitizer: tsan
|
||||||
|
- running_mode: "multi-tier-jit"
|
||||||
|
sanitizer: tsan
|
||||||
# classic-interp and fast-interp don't support simd
|
# classic-interp and fast-interp don't support simd
|
||||||
- running_mode: "classic-interp"
|
- running_mode: "classic-interp"
|
||||||
test_option: $SIMD_TEST_OPTIONS
|
test_option: $SIMD_TEST_OPTIONS
|
||||||
|
@ -595,9 +616,10 @@ jobs:
|
||||||
|| matrix.test_option == '$WASI_TEST_OPTIONS')
|
|| matrix.test_option == '$WASI_TEST_OPTIONS')
|
||||||
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
|
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
|
||||||
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
|
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: set sanitizer
|
- name: set additional tsan options
|
||||||
run: echo "WAMR_BUILD_SANITIZER=${{ matrix.sanitizer }}" >> $GITHUB_ENV
|
run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV
|
||||||
|
working-directory: tests/wamr-test-suites
|
||||||
|
|
||||||
#only download llvm libraries in jit and aot mode
|
#only download llvm libraries in jit and aot mode
|
||||||
- name: Get LLVM libraries
|
- name: Get LLVM libraries
|
||||||
|
@ -638,7 +660,7 @@ jobs:
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
timeout-minutes: 40
|
timeout-minutes: 40
|
||||||
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
|
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} -T %{{matrix.sanitizer}}
|
||||||
working-directory: ./tests/wamr-test-suites
|
working-directory: ./tests/wamr-test-suites
|
||||||
|
|
||||||
#only install x32 support libraries when to run x86_32 cases
|
#only install x32 support libraries when to run x86_32 cases
|
||||||
|
|
4
.github/workflows/spec_test_on_nuttx.yml
vendored
4
.github/workflows/spec_test_on_nuttx.yml
vendored
|
@ -52,9 +52,9 @@ jobs:
|
||||||
- name: Install RISC-V Compilers
|
- name: Install RISC-V Compilers
|
||||||
if: contains(matrix.nuttx_board_config, 'risc-v')
|
if: contains(matrix.nuttx_board_config, 'risc-v')
|
||||||
run: |
|
run: |
|
||||||
curl -L -k https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz > riscv.tar.gz
|
curl -L https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v12.3.0-1/xpack-riscv-none-elf-gcc-12.3.0-1-linux-x64.tar.gz > riscv.tar.gz
|
||||||
tar xvf riscv.tar.gz
|
tar xvf riscv.tar.gz
|
||||||
echo "$PWD/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_PATH
|
echo "$PWD/xpack-riscv-none-elf-gcc-12.3.0-1/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install WASI-SDK
|
- name: Install WASI-SDK
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -165,7 +165,11 @@ file (GLOB header
|
||||||
)
|
)
|
||||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||||
|
|
||||||
enable_language (ASM)
|
if (WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||||
|
enable_language (ASM_MASM)
|
||||||
|
else()
|
||||||
|
enable_language (ASM)
|
||||||
|
endif()
|
||||||
|
|
||||||
include (${SHARED_PLATFORM_CONFIG})
|
include (${SHARED_PLATFORM_CONFIG})
|
||||||
include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake)
|
include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake)
|
||||||
|
|
|
@ -1467,7 +1467,7 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
|
||||||
if (total_size >= UINT32_MAX
|
if (total_size >= UINT32_MAX
|
||||||
|| !(section->section_body =
|
|| !(section->section_body =
|
||||||
os_mmap(NULL, (uint32)total_size, map_prot,
|
os_mmap(NULL, (uint32)total_size, map_prot,
|
||||||
map_flags))) {
|
map_flags, os_get_invalid_handle()))) {
|
||||||
app_manager_printf(
|
app_manager_printf(
|
||||||
"Allocate executable memory failed!\n");
|
"Allocate executable memory failed!\n");
|
||||||
SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
|
SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
|
||||||
|
|
|
@ -315,6 +315,11 @@
|
||||||
#define BH_ENABLE_GC_VERIFY 0
|
#define BH_ENABLE_GC_VERIFY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Heap corruption check, enabled by default */
|
||||||
|
#ifndef BH_ENABLE_GC_CORRUPTION_CHECK
|
||||||
|
#define BH_ENABLE_GC_CORRUPTION_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable global heap pool if heap verification is enabled */
|
/* Enable global heap pool if heap verification is enabled */
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
#define WASM_ENABLE_GLOBAL_HEAP_POOL 1
|
||||||
|
|
|
@ -1574,8 +1574,9 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
|
|
||||||
/* Allocate memory for data */
|
/* Allocate memory for data */
|
||||||
if (data_sections[i].size > 0
|
if (data_sections[i].size > 0
|
||||||
&& !(data_sections[i].data = os_mmap(NULL, data_sections[i].size,
|
&& !(data_sections[i].data =
|
||||||
map_prot, map_flags))) {
|
os_mmap(NULL, data_sections[i].size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2470,7 +2471,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
|
|
||||||
if (size > UINT32_MAX
|
if (size > UINT32_MAX
|
||||||
|| !(module->extra_plt_data =
|
|| !(module->extra_plt_data =
|
||||||
os_mmap(NULL, (uint32)size, map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -2593,7 +2595,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
size = (uint64)sizeof(void *) * got_item_count;
|
size = (uint64)sizeof(void *) * got_item_count;
|
||||||
if (size > UINT32_MAX
|
if (size > UINT32_MAX
|
||||||
|| !(module->got_func_ptrs =
|
|| !(module->got_func_ptrs =
|
||||||
os_mmap(NULL, (uint32)size, map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -3106,8 +3109,9 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
|
||||||
(uint64)section_size + aot_get_plt_table_size();
|
(uint64)section_size + aot_get_plt_table_size();
|
||||||
total_size = (total_size + 3) & ~((uint64)3);
|
total_size = (total_size + 3) & ~((uint64)3);
|
||||||
if (total_size >= UINT32_MAX
|
if (total_size >= UINT32_MAX
|
||||||
|| !(aot_text = os_mmap(NULL, (uint32)total_size,
|
|| !(aot_text =
|
||||||
map_prot, map_flags))) {
|
os_mmap(NULL, (uint32)total_size, map_prot,
|
||||||
|
map_flags, os_get_invalid_handle()))) {
|
||||||
wasm_runtime_free(section);
|
wasm_runtime_free(section);
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"mmap memory failed");
|
"mmap memory failed");
|
||||||
|
|
|
@ -489,6 +489,12 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||||
max_page_count = DEFAULT_MAX_PAGES;
|
max_page_count = DEFAULT_MAX_PAGES;
|
||||||
}
|
}
|
||||||
|
else { /* heap_size == 0 */
|
||||||
|
if (init_page_count == DEFAULT_MAX_PAGES) {
|
||||||
|
num_bytes_per_page = UINT32_MAX;
|
||||||
|
init_page_count = max_page_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_VERBOSE("Memory instantiate:");
|
LOG_VERBOSE("Memory instantiate:");
|
||||||
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
||||||
|
@ -531,8 +537,8 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
* both i and memarg.offset are u32 in range 0 to 4G
|
* both i and memarg.offset are u32 in range 0 to 4G
|
||||||
* so the range of ea is 0 to 8G
|
* so the range of ea is 0 to 8G
|
||||||
*/
|
*/
|
||||||
if (!(p = mapped_mem =
|
if (!(p = mapped_mem = os_mmap(NULL, map_size, MMAP_PROT_NONE,
|
||||||
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
|
MMAP_MAP_NONE, os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -554,8 +560,12 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
||||||
* again here */
|
* again here */
|
||||||
|
|
||||||
|
if (memory_data_size > UINT32_MAX)
|
||||||
|
memory_data_size = UINT32_MAX;
|
||||||
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
|
|
||||||
memory_inst->module_type = Wasm_Module_AoT;
|
memory_inst->module_type = Wasm_Module_AoT;
|
||||||
|
@ -972,7 +982,8 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
wasm functions, and ensure that the exec_env's module inst
|
wasm functions, and ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env_main->module_inst;
|
module_inst_main = exec_env_main->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Try using the existing exec_env */
|
/* Try using the existing exec_env */
|
||||||
|
@ -997,7 +1008,8 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env->module_inst;
|
module_inst_main = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,12 +1059,12 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
|
||||||
fail:
|
fail:
|
||||||
if (is_sub_inst) {
|
if (is_sub_inst) {
|
||||||
/* Restore the parent exec_env's module inst */
|
/* Restore the parent exec_env's module inst */
|
||||||
exec_env_main->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (module_inst_main)
|
if (module_inst_main)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_main);
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
}
|
}
|
||||||
|
@ -1703,7 +1715,8 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,7 +1727,7 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1770,7 +1783,8 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1778,7 +1792,7 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
|
|
@ -388,6 +388,18 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
{
|
{
|
||||||
float32 f32 = strtof(argv[i], &endptr);
|
float32 f32 = strtof(argv[i], &endptr);
|
||||||
if (isnan(f32)) {
|
if (isnan(f32)) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/*
|
||||||
|
* Spec tests require the binary representation of NaN to be
|
||||||
|
* 0x7fc00000 for float and 0x7ff8000000000000 for float;
|
||||||
|
* however, in MSVC compiler, strtof doesn't return this
|
||||||
|
* exact value, causing some of the spec test failures. We
|
||||||
|
* use the value returned by nan/nanf as it is the one
|
||||||
|
* expected by spec tests.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
f32 = nanf("");
|
||||||
|
#endif
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
union ieee754_float u;
|
union ieee754_float u;
|
||||||
u.f = f32;
|
u.f = f32;
|
||||||
|
@ -422,6 +434,9 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
} u;
|
} u;
|
||||||
u.val = strtod(argv[i], &endptr);
|
u.val = strtod(argv[i], &endptr);
|
||||||
if (isnan(u.val)) {
|
if (isnan(u.val)) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
u.val = nan("");
|
||||||
|
#endif
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
union ieee754_double ud;
|
union ieee754_double ud;
|
||||||
ud.d = u.val;
|
ud.d = u.val;
|
||||||
|
@ -585,7 +600,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
{
|
{
|
||||||
#if UINTPTR_MAX == UINT32_MAX
|
#if UINTPTR_MAX == UINT32_MAX
|
||||||
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
|
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
|
||||||
os_printf("%p:ref.extern", (void *)argv1[k]);
|
os_printf("0x%" PRIxPTR ":ref.extern", (void *)argv1[k]);
|
||||||
else
|
else
|
||||||
os_printf("extern:ref.null");
|
os_printf("extern:ref.null");
|
||||||
k++;
|
k++;
|
||||||
|
@ -598,7 +613,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||||
u.parts[1] = argv1[k + 1];
|
u.parts[1] = argv1[k + 1];
|
||||||
k += 2;
|
k += 2;
|
||||||
if (u.val && u.val != (uintptr_t)-1LL)
|
if (u.val && u.val != (uintptr_t)-1LL)
|
||||||
os_printf("%p:ref.extern", (void *)u.val);
|
os_printf("0x%" PRIxPTR ":ref.extern", (void *)u.val);
|
||||||
else
|
else
|
||||||
os_printf("extern:ref.null");
|
os_printf("extern:ref.null");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,7 +58,8 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
if (!(exec_env->exce_check_guard_page =
|
if (!(exec_env->exce_check_guard_page =
|
||||||
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
|
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE,
|
||||||
|
os_get_invalid_handle())))
|
||||||
goto fail5;
|
goto fail5;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -201,7 +202,52 @@ void
|
||||||
wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
|
wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
|
||||||
WASMModuleInstanceCommon *const module_inst)
|
WASMModuleInstanceCommon *const module_inst)
|
||||||
{
|
{
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_lock(exec_env);
|
||||||
|
#endif
|
||||||
exec_env->module_inst = module_inst;
|
exec_env->module_inst = module_inst;
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_unlock(exec_env);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_exec_env_restore_module_inst(
|
||||||
|
WASMExecEnv *exec_env, WASMModuleInstanceCommon *const module_inst_common)
|
||||||
|
{
|
||||||
|
WASMModuleInstanceCommon *old_module_inst_common = exec_env->module_inst;
|
||||||
|
WASMModuleInstance *old_module_inst =
|
||||||
|
(WASMModuleInstance *)old_module_inst_common;
|
||||||
|
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_common;
|
||||||
|
char cur_exception[EXCEPTION_BUF_LEN];
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_lock(exec_env);
|
||||||
|
#endif
|
||||||
|
exec_env->module_inst = module_inst_common;
|
||||||
|
/*
|
||||||
|
* propagate an exception if any.
|
||||||
|
*/
|
||||||
|
exception_lock(old_module_inst);
|
||||||
|
if (old_module_inst->cur_exception[0] != '\0') {
|
||||||
|
bh_memcpy_s(cur_exception, sizeof(cur_exception),
|
||||||
|
old_module_inst->cur_exception,
|
||||||
|
sizeof(old_module_inst->cur_exception));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cur_exception[0] = '\0';
|
||||||
|
}
|
||||||
|
exception_unlock(old_module_inst);
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
wasm_cluster_traverse_unlock(exec_env);
|
||||||
|
#endif
|
||||||
|
if (cur_exception[0] != '\0') {
|
||||||
|
exception_lock(module_inst);
|
||||||
|
bh_memcpy_s(module_inst->cur_exception,
|
||||||
|
sizeof(module_inst->cur_exception), cur_exception,
|
||||||
|
sizeof(cur_exception));
|
||||||
|
exception_unlock(module_inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -291,6 +291,10 @@ void
|
||||||
wasm_exec_env_set_module_inst(
|
wasm_exec_env_set_module_inst(
|
||||||
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_exec_env_restore_module_inst(
|
||||||
|
WASMExecEnv *exec_env, struct WASMModuleInstanceCommon *const module_inst);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_exec_env_set_thread_info(WASMExecEnv *exec_env);
|
wasm_exec_env_set_thread_info(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
|
|
|
@ -2778,7 +2778,7 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
uint32 dir_count, const char *map_dir_list[],
|
uint32 dir_count, const char *map_dir_list[],
|
||||||
uint32 map_dir_count, const char *env_list[],
|
uint32 map_dir_count, const char *env_list[],
|
||||||
uint32 env_count, char *argv[], int argc,
|
uint32 env_count, char *argv[], int argc,
|
||||||
int stdinfd, int stdoutfd, int stderrfd)
|
int64 stdinfd, int64 stdoutfd, int64 stderrfd)
|
||||||
{
|
{
|
||||||
WASIArguments *wasi_args = get_wasi_args_from_module(module);
|
WASIArguments *wasi_args = get_wasi_args_from_module(module);
|
||||||
|
|
||||||
|
@ -2792,9 +2792,9 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
wasi_args->env_count = env_count;
|
wasi_args->env_count = env_count;
|
||||||
wasi_args->argv = argv;
|
wasi_args->argv = argv;
|
||||||
wasi_args->argc = (uint32)argc;
|
wasi_args->argc = (uint32)argc;
|
||||||
wasi_args->stdio[0] = stdinfd;
|
wasi_args->stdio[0] = (os_raw_file_handle)stdinfd;
|
||||||
wasi_args->stdio[1] = stdoutfd;
|
wasi_args->stdio[1] = (os_raw_file_handle)stdoutfd;
|
||||||
wasi_args->stdio[2] = stderrfd;
|
wasi_args->stdio[2] = (os_raw_file_handle)stderrfd;
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
#if WASM_ENABLE_INTERP != 0
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
@ -2889,8 +2889,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASIContext *wasi_ctx;
|
WASIContext *wasi_ctx;
|
||||||
char *argv_buf = NULL;
|
char *argv_buf = NULL;
|
||||||
|
@ -2908,7 +2909,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
bool argv_environ_inited = false;
|
bool argv_environ_inited = false;
|
||||||
bool addr_pool_inited = false;
|
bool addr_pool_inited = false;
|
||||||
__wasi_fd_t wasm_fd = 3;
|
__wasi_fd_t wasm_fd = 3;
|
||||||
int32 raw_fd;
|
os_file_handle file_handle;
|
||||||
char *path, resolved_path[PATH_MAX];
|
char *path, resolved_path[PATH_MAX];
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
|
@ -2978,15 +2979,19 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
}
|
}
|
||||||
addr_pool_inited = true;
|
addr_pool_inited = true;
|
||||||
|
|
||||||
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors.
|
os_file_handle stdin_file_handle = os_convert_stdin_handle(stdinfd);
|
||||||
*
|
os_file_handle stdout_file_handle = os_convert_stdout_handle(stdoutfd);
|
||||||
* If -1 is given, use STDIN_FILENO (0), STDOUT_FILENO (1),
|
os_file_handle stderr_file_handle = os_convert_stderr_handle(stderrfd);
|
||||||
* STDERR_FILENO (2) respectively.
|
|
||||||
*/
|
if (!os_is_handle_valid(&stdin_file_handle)
|
||||||
if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0)
|
|| !os_is_handle_valid(&stdout_file_handle)
|
||||||
|| !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1)
|
|| !os_is_handle_valid(&stderr_file_handle))
|
||||||
|| !fd_table_insert_existing(curfds, 2,
|
goto fail;
|
||||||
(stderrfd != -1) ? stderrfd : 2)) {
|
|
||||||
|
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
|
||||||
|
if (!fd_table_insert_existing(curfds, 0, stdin_file_handle, true)
|
||||||
|
|| !fd_table_insert_existing(curfds, 1, stdout_file_handle, true)
|
||||||
|
|| !fd_table_insert_existing(curfds, 2, stderr_file_handle, true)) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"Init wasi environment failed: init fd table failed");
|
"Init wasi environment failed: init fd table failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -2994,7 +2999,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
||||||
wasm_fd = 3;
|
wasm_fd = 3;
|
||||||
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
||||||
path = realpath(dir_list[i], resolved_path);
|
path = os_realpath(dir_list[i], resolved_path);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
|
@ -3003,22 +3008,31 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
|
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
|
||||||
if (raw_fd == -1) {
|
|
||||||
|
if (error != __WASI_ESUCCESS) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
"error while pre-opening directory %s: %d\n",
|
"error while pre-opening directory %s: %d\n",
|
||||||
dir_list[i], errno);
|
dir_list[i], error);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fd_table_insert_existing(curfds, wasm_fd, raw_fd)
|
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)) {
|
||||||
|| !fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
|
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(
|
snprintf(error_buf, error_buf_size,
|
||||||
error_buf, error_buf_size,
|
"error inserting preopen fd %u (directory %s) into fd "
|
||||||
"error while pre-opening directory %s: insertion failed\n",
|
"table",
|
||||||
dir_list[i]);
|
(unsigned int)wasm_fd, dir_list[i]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
|
||||||
|
if (error_buf)
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"error inserting preopen fd %u (directory %s) into "
|
||||||
|
"prestats table",
|
||||||
|
(unsigned int)wasm_fd, dir_list[i]);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3053,7 +3067,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = realpath(map_host, resolved_path);
|
path = os_realpath(map_host, resolved_path);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
|
@ -3064,8 +3078,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
|
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
|
||||||
if (raw_fd == -1) {
|
if (error != __WASI_ESUCCESS) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
"error while pre-opening mapped directory %s: %d\n",
|
"error while pre-opening mapped directory %s: %d\n",
|
||||||
|
@ -3075,7 +3089,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fd_table_insert_existing(curfds, wasm_fd, raw_fd)
|
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)
|
||||||
|| !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
|
|| !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
|
||||||
if (error_buf)
|
if (error_buf)
|
||||||
snprintf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size,
|
||||||
|
@ -3216,8 +3230,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size)
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASIContext *ctx;
|
WASIContext *ctx;
|
||||||
uvwasi_t *uvwasi;
|
uvwasi_t *uvwasi;
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "wasm_native.h"
|
#include "wasm_native.h"
|
||||||
#include "../include/wasm_export.h"
|
#include "../include/wasm_export.h"
|
||||||
#include "../interpreter/wasm.h"
|
#include "../interpreter/wasm.h"
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
#if WASM_ENABLE_UVWASI == 0
|
#if WASM_ENABLE_UVWASI == 0
|
||||||
#include "wasmtime_ssp.h"
|
|
||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
#else
|
#else
|
||||||
#include "uvwasi.h"
|
#include "uvwasi.h"
|
||||||
|
@ -44,15 +44,16 @@ extern "C" {
|
||||||
|
|
||||||
/* For STORE opcodes */
|
/* For STORE opcodes */
|
||||||
#define STORE_I64 PUT_I64_TO_ADDR
|
#define STORE_I64 PUT_I64_TO_ADDR
|
||||||
#define STORE_U32(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U32(void *addr, uint32_t value)
|
||||||
*(uint32 *)(addr) = (uint32)(value); \
|
{
|
||||||
} while (0)
|
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||||
#define STORE_U16(addr, value) \
|
}
|
||||||
do { \
|
static inline void
|
||||||
*(uint16 *)(addr) = (uint16)(value); \
|
STORE_U16(void *addr, uint16_t value)
|
||||||
} while (0)
|
{
|
||||||
|
*(uint16_t *)(addr) = (uint16_t)(value);
|
||||||
|
}
|
||||||
/* For LOAD opcodes */
|
/* For LOAD opcodes */
|
||||||
#define LOAD_I64(addr) (*(int64 *)(addr))
|
#define LOAD_I64(addr) (*(int64 *)(addr))
|
||||||
#define LOAD_F64(addr) (*(float64 *)(addr))
|
#define LOAD_F64(addr) (*(float64 *)(addr))
|
||||||
|
@ -147,42 +148,42 @@ GET_F64_FROM_ADDR(uint32 *addr)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STORE_U32(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U32(void *addr, uint32_t value)
|
||||||
uintptr_t addr_ = (uintptr_t)(addr); \
|
{
|
||||||
union { \
|
uintptr_t addr_ = (uintptr_t)(addr);
|
||||||
uint32 val; \
|
union {
|
||||||
uint16 u16[2]; \
|
uint32_t val;
|
||||||
uint8 u8[4]; \
|
uint16_t u16[2];
|
||||||
} u; \
|
uint8_t u8[4];
|
||||||
if ((addr_ & (uintptr_t)3) == 0) \
|
} u;
|
||||||
*(uint32 *)(addr) = (uint32)(value); \
|
if ((addr_ & (uintptr_t)3) == 0)
|
||||||
else { \
|
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||||
u.val = (uint32)(value); \
|
else {
|
||||||
if ((addr_ & (uintptr_t)1) == 0) { \
|
u.val = (uint32_t)(value);
|
||||||
((uint16 *)(addr))[0] = u.u16[0]; \
|
if ((addr_ & (uintptr_t)1) == 0) {
|
||||||
((uint16 *)(addr))[1] = u.u16[1]; \
|
((uint16_t *)(addr))[0] = u.u16[0];
|
||||||
} \
|
((uint16_t *)(addr))[1] = u.u16[1];
|
||||||
else { \
|
}
|
||||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
else {
|
||||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
((uint8_t *)(addr))[0] = u.u8[0];
|
||||||
((uint8 *)(addr))[2] = u.u8[2]; \
|
((uint8_t *)(addr))[1] = u.u8[1];
|
||||||
((uint8 *)(addr))[3] = u.u8[3]; \
|
((uint8_t *)(addr))[2] = u.u8[2];
|
||||||
} \
|
((uint8_t *)(addr))[3] = u.u8[3];
|
||||||
} \
|
}
|
||||||
} while (0)
|
}
|
||||||
|
}
|
||||||
#define STORE_U16(addr, value) \
|
static inline void
|
||||||
do { \
|
STORE_U16(void *addr, uint16_t value)
|
||||||
union { \
|
{
|
||||||
uint16 val; \
|
union {
|
||||||
uint8 u8[2]; \
|
uint16_t val;
|
||||||
} u; \
|
uint8_t u8[2];
|
||||||
u.val = (uint16)(value); \
|
} u;
|
||||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
u.val = (uint16_t)(value);
|
||||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
((uint8_t *)(addr))[0] = u.u8[0];
|
||||||
} while (0)
|
((uint8_t *)(addr))[1] = u.u8[1];
|
||||||
|
}
|
||||||
/* For LOAD opcodes */
|
/* For LOAD opcodes */
|
||||||
static inline int64
|
static inline int64
|
||||||
LOAD_I64(void *addr)
|
LOAD_I64(void *addr)
|
||||||
|
@ -861,7 +862,7 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
|
||||||
uint32 dir_count, const char *map_dir_list[],
|
uint32 dir_count, const char *map_dir_list[],
|
||||||
uint32 map_dir_count, const char *env_list[],
|
uint32 map_dir_count, const char *env_list[],
|
||||||
uint32 env_count, char *argv[], int argc,
|
uint32 env_count, char *argv[], int argc,
|
||||||
int stdinfd, int stdoutfd, int stderrfd);
|
int64 stdinfd, int64 stdoutfd, int64 stderrfd);
|
||||||
|
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
@ -889,8 +890,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *env[], uint32 env_count,
|
const char *env[], uint32 env_count,
|
||||||
const char *addr_pool[], uint32 addr_pool_size,
|
const char *addr_pool[], uint32 addr_pool_size,
|
||||||
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
|
||||||
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
|
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
|
||||||
int stderrfd, char *error_buf, uint32 error_buf_size);
|
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
|
||||||
|
char *error_buf, uint32 error_buf_size);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);
|
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
|
@ -344,7 +344,9 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
||||||
for (i = 0; i < block->param_count; i++) {
|
for (i = 0; i < block->param_count; i++) {
|
||||||
param_index = block->param_count - 1 - i;
|
param_index = block->param_count - 1 - i;
|
||||||
POP(value, block->param_types[param_index]);
|
POP(value, block->param_types[param_index]);
|
||||||
ADD_TO_PARAM_PHIS(block, value, param_index);
|
if (block->llvm_entry_block)
|
||||||
|
/* Only add incoming phis if the entry block was created */
|
||||||
|
ADD_TO_PARAM_PHIS(block, value, param_index);
|
||||||
if (block->label_type == LABEL_TYPE_IF
|
if (block->label_type == LABEL_TYPE_IF
|
||||||
&& !block->skip_wasm_code_else) {
|
&& !block->skip_wasm_code_else) {
|
||||||
if (block->llvm_else_block) {
|
if (block->llvm_else_block) {
|
||||||
|
@ -366,7 +368,17 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
|
||||||
|
|
||||||
/* Push param phis to the new block */
|
/* Push param phis to the new block */
|
||||||
for (i = 0; i < block->param_count; i++) {
|
for (i = 0; i < block->param_count; i++) {
|
||||||
PUSH(block->param_phis[i], block->param_types[i]);
|
if (block->llvm_entry_block)
|
||||||
|
/* Push param phis if the entry basic block was created */
|
||||||
|
PUSH(block->param_phis[i], block->param_types[i]);
|
||||||
|
else {
|
||||||
|
bh_assert(block->label_type == LABEL_TYPE_IF
|
||||||
|
&& block->llvm_else_block && block->else_param_phis
|
||||||
|
&& !block->skip_wasm_code_else);
|
||||||
|
/* Push else param phis if we start to translate the
|
||||||
|
else branch */
|
||||||
|
PUSH(block->else_param_phis[i], block->param_types[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -157,7 +157,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
|
|
||||||
if (mem_offset + bytes <= mem_data_size) {
|
if (mem_offset + bytes <= mem_data_size) {
|
||||||
/* inside memory space */
|
/* inside memory space */
|
||||||
offset1 = I32_CONST((uint32)mem_offset);
|
if (comp_ctx->pointer_size == sizeof(uint64))
|
||||||
|
offset1 = I64_CONST((uint32)mem_offset);
|
||||||
|
else
|
||||||
|
offset1 = I32_CONST((uint32)mem_offset);
|
||||||
CHECK_LLVM_CONST(offset1);
|
CHECK_LLVM_CONST(offset1);
|
||||||
if (!enable_segue) {
|
if (!enable_segue) {
|
||||||
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder,
|
if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder,
|
||||||
|
|
|
@ -777,17 +777,25 @@ compile_int_rot(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
|
||||||
if (IS_CONST_ZERO(right))
|
if (IS_CONST_ZERO(right))
|
||||||
return left;
|
return left;
|
||||||
|
|
||||||
/* Calculate (bits - shif_count) */
|
/* Calculate (bits - shift_count) */
|
||||||
LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
|
LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count,
|
||||||
"bits_minus_shift_count", NULL);
|
"bits_minus_shift_count", NULL);
|
||||||
|
/* Calculate (bits - shift_count) & mask */
|
||||||
|
bits_minus_shift_count =
|
||||||
|
LLVMBuildAnd(comp_ctx->builder, bits_minus_shift_count,
|
||||||
|
is_i32 ? I32_31 : I64_63, "bits_minus_shift_count_and");
|
||||||
|
if (!bits_minus_shift_count) {
|
||||||
|
aot_set_last_error("llvm build and failed.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_rotl) {
|
if (is_rotl) {
|
||||||
/* left<<count | left>>(BITS-count) */
|
/* (left << count) | (left >> ((BITS - count) & mask)) */
|
||||||
LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL);
|
LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL);
|
||||||
LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* left>>count | left<<(BITS-count) */
|
/* (left >> count) | (left << ((BITS - count) & mask)) */
|
||||||
LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL);
|
LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL);
|
||||||
LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,13 @@ aot_target_precheck_can_use_musttail(const AOTCompContext *comp_ctx)
|
||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (strstr(comp_ctx->target_arch, "thumb")) {
|
||||||
|
/*
|
||||||
|
* cf.
|
||||||
|
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2412
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* x86-64/i386: true
|
* x86-64/i386: true
|
||||||
*
|
*
|
||||||
|
@ -1915,6 +1922,7 @@ static ArchItem valid_archs[] = {
|
||||||
static const char *valid_abis[] = {
|
static const char *valid_abis[] = {
|
||||||
"gnu",
|
"gnu",
|
||||||
"eabi",
|
"eabi",
|
||||||
|
"eabihf",
|
||||||
"gnueabihf",
|
"gnueabihf",
|
||||||
"msvc",
|
"msvc",
|
||||||
"ilp32",
|
"ilp32",
|
||||||
|
@ -1992,6 +2000,18 @@ get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size)
|
||||||
bh_assert(*triple == '-' || *triple == '\0');
|
bh_assert(*triple == '-' || *triple == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_baremetal_target(const char *target, const char *cpu, const char *abi)
|
||||||
|
{
|
||||||
|
/* TODO: support more baremetal targets */
|
||||||
|
if (target) {
|
||||||
|
/* If target is thumbxxx, then it is baremetal target */
|
||||||
|
if (!strncmp(target, "thumb", strlen("thumb")))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
aot_handle_llvm_errmsg(const char *string, LLVMErrorRef err)
|
aot_handle_llvm_errmsg(const char *string, LLVMErrorRef err)
|
||||||
{
|
{
|
||||||
|
@ -2214,7 +2234,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
char *triple_norm_new = NULL, *cpu_new = NULL;
|
char *triple_norm_new = NULL, *cpu_new = NULL;
|
||||||
char *err = NULL, *fp_round = "round.tonearest",
|
char *err = NULL, *fp_round = "round.tonearest",
|
||||||
*fp_exce = "fpexcept.strict";
|
*fp_exce = "fpexcept.strict";
|
||||||
char triple_buf[32] = { 0 }, features_buf[128] = { 0 };
|
char triple_buf[128] = { 0 }, features_buf[128] = { 0 };
|
||||||
uint32 opt_level, size_level, i;
|
uint32 opt_level, size_level, i;
|
||||||
LLVMCodeModel code_model;
|
LLVMCodeModel code_model;
|
||||||
LLVMTargetDataRef target_data_ref;
|
LLVMTargetDataRef target_data_ref;
|
||||||
|
@ -2510,6 +2530,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
* for Windows/MacOS under Linux host, or generating AOT file for
|
* for Windows/MacOS under Linux host, or generating AOT file for
|
||||||
* Linux/MacOS under Windows host.
|
* Linux/MacOS under Windows host.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!strcmp(abi, "msvc")) {
|
if (!strcmp(abi, "msvc")) {
|
||||||
if (!strcmp(arch1, "i386"))
|
if (!strcmp(arch1, "i386"))
|
||||||
vendor_sys = "-pc-win32-";
|
vendor_sys = "-pc-win32-";
|
||||||
|
@ -2517,7 +2538,10 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
vendor_sys = "-pc-windows-";
|
vendor_sys = "-pc-windows-";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vendor_sys = "-pc-linux-";
|
if (is_baremetal_target(arch, cpu, abi))
|
||||||
|
vendor_sys = "-unknown-none-";
|
||||||
|
else
|
||||||
|
vendor_sys = "-pc-linux-";
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_assert(strlen(arch1) + strlen(vendor_sys) + strlen(abi)
|
bh_assert(strlen(arch1) + strlen(vendor_sys) + strlen(abi)
|
||||||
|
@ -2553,6 +2577,11 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||||
if (!abi)
|
if (!abi)
|
||||||
abi = "msvc";
|
abi = "msvc";
|
||||||
}
|
}
|
||||||
|
else if (is_baremetal_target(arch, cpu, abi)) {
|
||||||
|
vendor_sys = "-unknown-none-";
|
||||||
|
if (!abi)
|
||||||
|
abi = "gnu";
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
vendor_sys = "-pc-linux-";
|
vendor_sys = "-pc-linux-";
|
||||||
if (!abi)
|
if (!abi)
|
||||||
|
|
|
@ -30,11 +30,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
LLVM_CONST(i16x8_vec_zero),
|
LLVM_CONST(i16x8_vec_zero),
|
||||||
LLVM_CONST(i32x4_vec_zero),
|
LLVM_CONST(i32x4_vec_zero),
|
||||||
LLVM_CONST(i64x2_vec_zero) };
|
LLVM_CONST(i64x2_vec_zero) };
|
||||||
LLVMValueRef lane_bits[] = {
|
LLVMValueRef lane_shift_masks[] = {
|
||||||
LLVM_CONST(i32_eight),
|
LLVMConstInt(I32_TYPE, 7, true),
|
||||||
LLVMConstInt(I32_TYPE, 16, true),
|
LLVMConstInt(I32_TYPE, 15, true),
|
||||||
LLVMConstInt(I32_TYPE, 32, true),
|
LLVMConstInt(I32_TYPE, 31, true),
|
||||||
LLVMConstInt(I32_TYPE, 64, true),
|
LLVMConstInt(I32_TYPE, 63, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
POP_I32(offset);
|
POP_I32(offset);
|
||||||
|
@ -44,11 +44,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* offset mod LaneBits */
|
/* offset = offset & shift_mask */
|
||||||
if (!lane_bits[itype]
|
if (!lane_shift_masks[itype]
|
||||||
|| !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype],
|
|| !(offset = LLVMBuildAnd(comp_ctx->builder, offset,
|
||||||
"offset_fix"))) {
|
lane_shift_masks[itype], "offset_fix"))) {
|
||||||
HANDLE_FAILURE("LLVMBuildSRem");
|
HANDLE_FAILURE("LLVMBuildAnd");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
|
||||||
POP_F32(rhs);
|
POP_F32(rhs);
|
||||||
POP_F32(lhs);
|
POP_F32(lhs);
|
||||||
|
|
||||||
if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
|
if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
|
||||||
float32 lvalue = jit_cc_get_const_F32(cc, lhs);
|
float32 lvalue = jit_cc_get_const_F32(cc, lhs);
|
||||||
float32 rvalue = jit_cc_get_const_F32(cc, rhs);
|
float32 rvalue = jit_cc_get_const_F32(cc, rhs);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
|
||||||
POP_F64(rhs);
|
POP_F64(rhs);
|
||||||
POP_F64(lhs);
|
POP_F64(lhs);
|
||||||
|
|
||||||
if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
|
if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) {
|
||||||
float64 lvalue = jit_cc_get_const_F64(cc, lhs);
|
float64 lvalue = jit_cc_get_const_F64(cc, lhs);
|
||||||
float64 rvalue = jit_cc_get_const_F64(cc, rhs);
|
float64 rvalue = jit_cc_get_const_F64(cc, rhs);
|
||||||
|
|
||||||
|
|
|
@ -808,7 +808,7 @@ jit_compile_op_block(JitCompContext *cc, uint8 **p_frame_ip,
|
||||||
else if (label_type == LABEL_TYPE_IF) {
|
else if (label_type == LABEL_TYPE_IF) {
|
||||||
POP_I32(value);
|
POP_I32(value);
|
||||||
|
|
||||||
if (!jit_reg_is_const_val(value)) {
|
if (!jit_reg_is_const(value)) {
|
||||||
/* Compare value is not constant, create condition br IR */
|
/* Compare value is not constant, create condition br IR */
|
||||||
|
|
||||||
/* Create entry block */
|
/* Create entry block */
|
||||||
|
|
|
@ -827,23 +827,45 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
|
||||||
JitReg *params, uint32 param_count)
|
JitReg *params, uint32 param_count)
|
||||||
{
|
{
|
||||||
JitInsn *insn;
|
JitInsn *insn;
|
||||||
|
char *i32_arg_names[] = { "edi", "esi", "edx", "ecx" };
|
||||||
char *i64_arg_names[] = { "rdi", "rsi", "rdx", "rcx", "r8", "r9" };
|
char *i64_arg_names[] = { "rdi", "rsi", "rdx", "rcx", "r8", "r9" };
|
||||||
char *f32_arg_names[] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" };
|
char *f32_arg_names[] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" };
|
||||||
char *f64_arg_names[] = { "xmm0_f64", "xmm1_f64", "xmm2_f64",
|
char *f64_arg_names[] = { "xmm0_f64", "xmm1_f64", "xmm2_f64",
|
||||||
"xmm3_f64", "xmm4_f64", "xmm5_f64" };
|
"xmm3_f64", "xmm4_f64", "xmm5_f64" };
|
||||||
JitReg i64_arg_regs[6], f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
|
JitReg i32_arg_regs[4], i64_arg_regs[6];
|
||||||
|
JitReg f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
|
||||||
JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax");
|
JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax");
|
||||||
JitReg xmm0_hreg = jit_codegen_get_hreg_by_name("xmm0");
|
JitReg xmm0_hreg = jit_codegen_get_hreg_by_name("xmm0");
|
||||||
uint32 i, i64_reg_idx, float_reg_idx;
|
uint32 i, i64_reg_idx, float_reg_idx, lock_i32_reg_num;
|
||||||
|
|
||||||
bh_assert(param_count <= 6);
|
bh_assert(param_count <= 6);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
i32_arg_regs[i] = jit_codegen_get_hreg_by_name(i32_arg_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
i64_arg_regs[i] = jit_codegen_get_hreg_by_name(i64_arg_names[i]);
|
i64_arg_regs[i] = jit_codegen_get_hreg_by_name(i64_arg_names[i]);
|
||||||
f32_arg_regs[i] = jit_codegen_get_hreg_by_name(f32_arg_names[i]);
|
f32_arg_regs[i] = jit_codegen_get_hreg_by_name(f32_arg_names[i]);
|
||||||
f64_arg_regs[i] = jit_codegen_get_hreg_by_name(f64_arg_names[i]);
|
f64_arg_regs[i] = jit_codegen_get_hreg_by_name(f64_arg_names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock_i32_reg_num = param_count < 4 ? param_count : 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock i32 registers so that they won't be allocated for the operand
|
||||||
|
* of below I32TOI64 insn, which may have been overwritten in the
|
||||||
|
* previous MOV, for example, in the below insns:
|
||||||
|
* MOV I5, I15
|
||||||
|
* I32TOI64 I6, i5
|
||||||
|
* CALLNATIVE VOID, native_func, I5, I6
|
||||||
|
* i5 is used in the second insn, but it has been overwritten in I5
|
||||||
|
* by the first insn
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lock_i32_reg_num; i++) {
|
||||||
|
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
i64_reg_idx = float_reg_idx = 0;
|
i64_reg_idx = float_reg_idx = 0;
|
||||||
for (i = 0; i < param_count; i++) {
|
for (i = 0; i < param_count; i++) {
|
||||||
switch (jit_reg_kind(params[i])) {
|
switch (jit_reg_kind(params[i])) {
|
||||||
|
@ -865,6 +887,14 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Announce the locked i32 registers are being used, and do necessary
|
||||||
|
* spill ASAP
|
||||||
|
*/
|
||||||
|
for (i = 0; i < lock_i32_reg_num; i++) {
|
||||||
|
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
switch (jit_reg_kind(res)) {
|
switch (jit_reg_kind(res)) {
|
||||||
case JIT_REG_KIND_I32:
|
case JIT_REG_KIND_I32:
|
||||||
|
|
|
@ -17,8 +17,8 @@ jit_code_cache_init(uint32 code_cache_size)
|
||||||
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
||||||
int map_flags = MMAP_MAP_NONE;
|
int map_flags = MMAP_MAP_NONE;
|
||||||
|
|
||||||
if (!(code_cache_pool =
|
if (!(code_cache_pool = os_mmap(NULL, code_cache_size, map_prot, map_flags,
|
||||||
os_mmap(NULL, code_cache_size, map_prot, map_flags))) {
|
os_get_invalid_handle()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -432,26 +432,31 @@ wasm_runtime_get_module_hash(wasm_module_t module);
|
||||||
* @param env_count The number of elements in env.
|
* @param env_count The number of elements in env.
|
||||||
* @param argv The list of command line arguments.
|
* @param argv The list of command line arguments.
|
||||||
* @param argc The number of elements in argv.
|
* @param argc The number of elements in argv.
|
||||||
* @param stdinfd The host file descriptor to back WASI STDIN_FILENO.
|
* @param stdin_handle The raw host handle to back WASI STDIN_FILENO.
|
||||||
* If -1 is specified, STDIN_FILENO is used.
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
* @param stdoutfd The host file descriptor to back WASI STDOUT_FILENO.
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
* If -1 is specified, STDOUT_FILENO is used.
|
* for STDIN is used.
|
||||||
* @param stderrfd The host file descriptor to back WASI STDERR_FILENO.
|
* @param stdoutfd The raw host handle to back WASI STDOUT_FILENO.
|
||||||
* If -1 is specified, STDERR_FILENO is used.
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
|
* for STDOUT is used.
|
||||||
|
* @param stderrfd The raw host handle to back WASI STDERR_FILENO.
|
||||||
|
* If an invalid handle is specified (e.g. -1 on POSIX,
|
||||||
|
* INVALID_HANDLE_VALUE on Windows), the platform default
|
||||||
|
* for STDERR is used.
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_wasi_args_ex(wasm_module_t module,
|
wasm_runtime_set_wasi_args_ex(wasm_module_t module,
|
||||||
const char *dir_list[], uint32_t dir_count,
|
const char *dir_list[], uint32_t dir_count,
|
||||||
const char *map_dir_list[], uint32_t map_dir_count,
|
const char *map_dir_list[], uint32_t map_dir_count,
|
||||||
const char *env[], uint32_t env_count,
|
const char *env[], uint32_t env_count,
|
||||||
char *argv[], int argc,
|
char *argv[], int argc, int64_t stdinfd,
|
||||||
int stdinfd, int stdoutfd, int stderrfd);
|
int64_t stdoutfd, int64_t stderrfd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set WASI parameters.
|
* Set WASI parameters.
|
||||||
*
|
*
|
||||||
* Same as wasm_runtime_set_wasi_args_ex with stdinfd = -1, stdoutfd = -1,
|
* Same as wasm_runtime_set_wasi_args_ex but with default stdio handles
|
||||||
* stderrfd = -1.
|
|
||||||
*/
|
*/
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_set_wasi_args(wasm_module_t module,
|
wasm_runtime_set_wasi_args(wasm_module_t module,
|
||||||
|
|
|
@ -403,7 +403,7 @@ typedef struct WASIArguments {
|
||||||
uint32 ns_lookup_count;
|
uint32 ns_lookup_count;
|
||||||
char **argv;
|
char **argv;
|
||||||
uint32 argc;
|
uint32 argc;
|
||||||
int stdio[3];
|
os_raw_file_handle stdio[3];
|
||||||
} WASIArguments;
|
} WASIArguments;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1034,7 +1034,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* - module_inst */
|
/* - module_inst */
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)sub_module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)sub_module_inst);
|
||||||
/* - aux_stack_boundary */
|
/* - aux_stack_boundary */
|
||||||
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
||||||
exec_env->aux_stack_boundary.boundary =
|
exec_env->aux_stack_boundary.boundary =
|
||||||
|
@ -1056,15 +1057,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
prev_frame->ip = ip;
|
prev_frame->ip = ip;
|
||||||
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
||||||
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_restore_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
/* transfer exception if it is thrown */
|
|
||||||
if (wasm_copy_exception(sub_module_inst, NULL)) {
|
|
||||||
bh_memcpy_s(module_inst->cur_exception,
|
|
||||||
sizeof(module_inst->cur_exception),
|
|
||||||
sub_module_inst->cur_exception,
|
|
||||||
sizeof(sub_module_inst->cur_exception));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1031,7 +1031,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* - module_inst */
|
/* - module_inst */
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)sub_module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)sub_module_inst);
|
||||||
/* - aux_stack_boundary */
|
/* - aux_stack_boundary */
|
||||||
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
aux_stack_origin_boundary = exec_env->aux_stack_boundary.boundary;
|
||||||
exec_env->aux_stack_boundary.boundary =
|
exec_env->aux_stack_boundary.boundary =
|
||||||
|
@ -1053,15 +1054,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||||
prev_frame->ip = ip;
|
prev_frame->ip = ip;
|
||||||
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
exec_env->aux_stack_boundary.boundary = aux_stack_origin_boundary;
|
||||||
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
exec_env->aux_stack_bottom.bottom = aux_stack_origin_bottom;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_restore_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
/* transfer exception if it is thrown */
|
|
||||||
if (wasm_copy_exception(sub_module_inst, NULL)) {
|
|
||||||
bh_memcpy_s(module_inst->cur_exception,
|
|
||||||
sizeof(module_inst->cur_exception),
|
|
||||||
sub_module_inst->cur_exception,
|
|
||||||
sizeof(sub_module_inst->cur_exception));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,6 @@ fail:
|
||||||
|
|
||||||
#define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p)
|
#define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p)
|
||||||
#define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p)
|
#define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p)
|
||||||
#define read_bool(p) TEMPLATE_READ_VALUE(bool, p)
|
|
||||||
|
|
||||||
#define read_leb_int64(p, p_end, res) \
|
#define read_leb_int64(p, p_end, res) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -490,6 +489,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
if (type != VALUE_TYPE_V128)
|
if (type != VALUE_TYPE_V128)
|
||||||
goto fail_type_mismatch;
|
goto fail_type_mismatch;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
flag = read_uint8(p);
|
flag = read_uint8(p);
|
||||||
(void)flag;
|
(void)flag;
|
||||||
|
|
||||||
|
@ -7456,6 +7456,7 @@ re_scan:
|
||||||
BlockType block_type;
|
BlockType block_type;
|
||||||
|
|
||||||
p_org = p - 1;
|
p_org = p - 1;
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
value_type = read_uint8(p);
|
value_type = read_uint8(p);
|
||||||
if (is_byte_a_type(value_type)) {
|
if (is_byte_a_type(value_type)) {
|
||||||
/* If the first byte is one of these special values:
|
/* If the first byte is one of these special values:
|
||||||
|
@ -9596,6 +9597,7 @@ re_scan:
|
||||||
{
|
{
|
||||||
uint32 opcode1;
|
uint32 opcode1;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
opcode1 = read_uint8(p);
|
opcode1 = read_uint8(p);
|
||||||
/* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h
|
/* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h
|
||||||
*/
|
*/
|
||||||
|
@ -10257,6 +10259,7 @@ re_scan:
|
||||||
{
|
{
|
||||||
uint32 opcode1;
|
uint32 opcode1;
|
||||||
|
|
||||||
|
CHECK_BUF(p, p_end, 1);
|
||||||
opcode1 = read_uint8(p);
|
opcode1 = read_uint8(p);
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
emit_byte(loader_ctx, opcode1);
|
emit_byte(loader_ctx, opcode1);
|
||||||
|
|
|
@ -276,6 +276,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
if (max_page_count > DEFAULT_MAX_PAGES)
|
if (max_page_count > DEFAULT_MAX_PAGES)
|
||||||
max_page_count = DEFAULT_MAX_PAGES;
|
max_page_count = DEFAULT_MAX_PAGES;
|
||||||
}
|
}
|
||||||
|
else { /* heap_size == 0 */
|
||||||
|
if (init_page_count == DEFAULT_MAX_PAGES) {
|
||||||
|
num_bytes_per_page = UINT32_MAX;
|
||||||
|
init_page_count = max_page_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_VERBOSE("Memory instantiate:");
|
LOG_VERBOSE("Memory instantiate:");
|
||||||
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
||||||
|
@ -318,14 +324,16 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
* so the range of ea is 0 to 8G
|
* so the range of ea is 0 to 8G
|
||||||
*/
|
*/
|
||||||
if (!(memory->memory_data = mapped_mem =
|
if (!(memory->memory_data = mapped_mem =
|
||||||
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
|
os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
if (!os_mem_commit(mapped_mem, memory_data_size,
|
if (memory_data_size > 0
|
||||||
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
&& !os_mem_commit(mapped_mem, memory_data_size,
|
||||||
|
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||||
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
@ -338,8 +346,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||||
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
/* Newly allocated pages are filled with zero by the OS, we don't fill it
|
||||||
* again here */
|
* again here */
|
||||||
|
|
||||||
|
if (memory_data_size > UINT32_MAX)
|
||||||
|
memory_data_size = UINT32_MAX;
|
||||||
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
|
|
||||||
memory->module_type = Wasm_Module_Bytecode;
|
memory->module_type = Wasm_Module_Bytecode;
|
||||||
|
@ -1050,7 +1062,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
wasm functions, and ensure that the exec_env's module inst
|
wasm functions, and ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env_main->module_inst;
|
module_inst_main = exec_env_main->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(exec_env,
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Try using the existing exec_env */
|
/* Try using the existing exec_env */
|
||||||
|
@ -1075,7 +1088,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_main = exec_env->module_inst;
|
module_inst_main = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,12 +1122,12 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
|
||||||
fail:
|
fail:
|
||||||
if (is_sub_inst) {
|
if (is_sub_inst) {
|
||||||
/* Restore the parent exec_env's module inst */
|
/* Restore the parent exec_env's module inst */
|
||||||
exec_env_main->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (module_inst_main)
|
if (module_inst_main)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_main;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_main);
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
}
|
}
|
||||||
|
@ -1182,7 +1196,8 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,7 +1208,7 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
@ -1249,7 +1264,8 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
module inst to ensure that the exec_env's module inst
|
module inst to ensure that the exec_env's module inst
|
||||||
is the correct one. */
|
is the correct one. */
|
||||||
module_inst_old = exec_env->module_inst;
|
module_inst_old = exec_env->module_inst;
|
||||||
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
|
wasm_exec_env_set_module_inst(
|
||||||
|
exec_env, (WASMModuleInstanceCommon *)module_inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,7 +1273,7 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
if (module_inst_old)
|
if (module_inst_old)
|
||||||
/* Restore the existing exec_env's module inst */
|
/* Restore the existing exec_env's module inst */
|
||||||
exec_env->module_inst = module_inst_old;
|
wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
|
||||||
|
|
||||||
if (exec_env_created)
|
if (exec_env_created)
|
||||||
wasm_exec_env_destroy(exec_env_created);
|
wasm_exec_env_destroy(exec_env_created);
|
||||||
|
|
3
core/iwasm/libraries/lib-socket/test/manifest.json
Normal file
3
core/iwasm/libraries/lib-socket/test/manifest.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "WAMR lib-socket tests"
|
||||||
|
}
|
|
@ -30,7 +30,16 @@
|
||||||
wasm_runtime_module_free(module_inst, offset)
|
wasm_runtime_module_free(module_inst, offset)
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
#define wasi_errno_t uvwasi_errno_t
|
// uvwasi_errno_t is typedef'd to uint16 which is correct according to the ABI
|
||||||
|
// specification. However, in WASM, the smallest integer type is int32. If we
|
||||||
|
// return uint16, we would rely on language SDKs to implement the correct
|
||||||
|
// behaviour of casting to uint16 before checking the value or using it any way.
|
||||||
|
// Failure to do so can cause tricky bugs as the upper 16 bits of the error
|
||||||
|
// result are not guaranteed to be zero'ed by us so the result essentially
|
||||||
|
// contains garbage from the WASM app perspective. To prevent this, we return
|
||||||
|
// uint32 directly instead so as not to be reliant on the correct behaviour of
|
||||||
|
// any current/future SDK implementations.
|
||||||
|
#define wasi_errno_t uint32_t
|
||||||
#define wasi_fd_t uvwasi_fd_t
|
#define wasi_fd_t uvwasi_fd_t
|
||||||
#define wasi_clockid_t uvwasi_clockid_t
|
#define wasi_clockid_t uvwasi_clockid_t
|
||||||
#define wasi_timestamp_t uvwasi_timestamp_t
|
#define wasi_timestamp_t uvwasi_timestamp_t
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
#include "wasm_runtime_common.h"
|
#include "wasm_runtime_common.h"
|
||||||
|
#include "wasmtime_ssp.h"
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
#include "../../../thread-mgr/thread_manager.h"
|
#include "../../../thread-mgr/thread_manager.h"
|
||||||
|
@ -192,7 +193,7 @@ wasi_clock_res_get(wasm_exec_env_t exec_env,
|
||||||
if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
|
if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
|
||||||
return (wasi_errno_t)-1;
|
return (wasi_errno_t)-1;
|
||||||
|
|
||||||
return wasmtime_ssp_clock_res_get(clock_id, resolution);
|
return os_clock_res_get(clock_id, resolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
|
@ -206,7 +207,7 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
|
||||||
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
|
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
|
||||||
return (wasi_errno_t)-1;
|
return (wasi_errno_t)-1;
|
||||||
|
|
||||||
return wasmtime_ssp_clock_time_get(clock_id, precision, time);
|
return os_clock_time_get(clock_id, precision, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static wasi_errno_t
|
static wasi_errno_t
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#ifndef _LIBC_WASI_WRAPPER_H
|
#ifndef _LIBC_WASI_WRAPPER_H
|
||||||
#define _LIBC_WASI_WRAPPER_H
|
#define _LIBC_WASI_WRAPPER_H
|
||||||
|
|
||||||
#include "wasmtime_ssp.h"
|
|
||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -19,7 +18,16 @@ typedef __wasi_advice_t wasi_advice_t;
|
||||||
typedef __wasi_ciovec_t wasi_ciovec_t;
|
typedef __wasi_ciovec_t wasi_ciovec_t;
|
||||||
typedef __wasi_clockid_t wasi_clockid_t;
|
typedef __wasi_clockid_t wasi_clockid_t;
|
||||||
typedef __wasi_dircookie_t wasi_dircookie_t;
|
typedef __wasi_dircookie_t wasi_dircookie_t;
|
||||||
typedef __wasi_errno_t wasi_errno_t;
|
// __wasi_errno_t is typedef'd to uint16 which is correct according to the ABI
|
||||||
|
// specification. However, in WASM, the smallest integer type is int32. If we
|
||||||
|
// return uint16, we would rely on language SDKs to implement the correct
|
||||||
|
// behaviour of casting to uint16 before checking the value or using it any way.
|
||||||
|
// Failure to do so can cause tricky bugs as the upper 16 bits of the error
|
||||||
|
// result are not guaranteed to be zero'ed by us so the result essentially
|
||||||
|
// contains garbage from the WASM app perspective. To prevent this, we return
|
||||||
|
// uint32 directly instead so as not to be reliant on the correct behaviour of
|
||||||
|
// any current/future WASI SDK implemenations.
|
||||||
|
typedef uint32_t wasi_errno_t;
|
||||||
typedef __wasi_event_t wasi_event_t;
|
typedef __wasi_event_t wasi_event_t;
|
||||||
typedef __wasi_exitcode_t wasi_exitcode_t;
|
typedef __wasi_exitcode_t wasi_exitcode_t;
|
||||||
typedef __wasi_fdflags_t wasi_fdflags_t;
|
typedef __wasi_fdflags_t wasi_fdflags_t;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,99 +8,68 @@
|
||||||
#include "ssp_config.h"
|
#include "ssp_config.h"
|
||||||
#include "blocking_op.h"
|
#include "blocking_op.h"
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_close(wasm_exec_env_t exec_env, int fd)
|
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
bool is_stdio)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
int ret = close(fd);
|
__wasi_errno_t error = os_close(handle, is_stdio);
|
||||||
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread)
|
||||||
|
{
|
||||||
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
|
return __WASI_EINTR;
|
||||||
|
}
|
||||||
|
__wasi_errno_t error = os_readv(handle, iov, iovcnt, nread);
|
||||||
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
|
__wasi_filesize_t offset, size_t *nread)
|
||||||
|
{
|
||||||
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
|
return __WASI_EINTR;
|
||||||
|
}
|
||||||
|
__wasi_errno_t ret = os_preadv(handle, iov, iovcnt, offset, nread);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
__wasi_errno_t
|
||||||
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int iovcnt)
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
|
size_t *nwritten)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
ssize_t ret = readv(fd, iov, iovcnt);
|
__wasi_errno_t error = os_writev(handle, iov, iovcnt, nwritten);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_HAS_PREADV
|
__wasi_errno_t
|
||||||
ssize_t
|
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
int iovcnt, off_t offset)
|
__wasi_filesize_t offset, size_t *nwritten)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
ssize_t ret = preadv(fd, iov, iovcnt, offset);
|
__wasi_errno_t error = os_pwritev(handle, iov, iovcnt, offset, nwritten);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
#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
|
int
|
||||||
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
||||||
|
@ -187,15 +156,17 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
|
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int oflags, mode_t mode)
|
const char *path, __wasi_oflags_t oflags,
|
||||||
|
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
|
||||||
|
wasi_libc_file_access_mode access_mode, os_file_handle *out)
|
||||||
{
|
{
|
||||||
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
if (!wasm_runtime_begin_blocking_op(exec_env)) {
|
||||||
errno = EINTR;
|
return __WASI_EINTR;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
int ret = openat(fd, path, oflags, mode);
|
__wasi_errno_t error = os_openat(handle, path, oflags, fd_flags,
|
||||||
|
lookup_flags, access_mode, out);
|
||||||
wasm_runtime_end_blocking_op(exec_env);
|
wasm_runtime_end_blocking_op(exec_env);
|
||||||
return ret;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,24 @@
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
|
|
||||||
int
|
__wasi_errno_t
|
||||||
blocking_op_close(wasm_exec_env_t exec_env, int fd);
|
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
bool is_stdio);
|
||||||
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
__wasi_errno_t
|
||||||
int iovcnt);
|
blocking_op_readv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
const struct __wasi_iovec_t *iov, int iovcnt, size_t *nread);
|
||||||
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
__wasi_errno_t
|
||||||
int iovcnt, off_t offset);
|
blocking_op_preadv(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
ssize_t
|
const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
|
__wasi_filesize_t offset, size_t *nread);
|
||||||
off_t offset);
|
__wasi_errno_t
|
||||||
ssize_t
|
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
int iovcnt);
|
size_t *nwritten);
|
||||||
ssize_t
|
__wasi_errno_t
|
||||||
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
|
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
int iovcnt, off_t offset);
|
const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
ssize_t
|
__wasi_filesize_t offset, size_t *nwritten);
|
||||||
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
|
|
||||||
off_t offset);
|
|
||||||
int
|
int
|
||||||
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
|
||||||
bh_socket_t *sockp, void *addr,
|
bh_socket_t *sockp, void *addr,
|
||||||
|
@ -47,6 +45,9 @@ blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
|
||||||
uint8_t *hint_is_ipv4,
|
uint8_t *hint_is_ipv4,
|
||||||
bh_addr_info_t *addr_info,
|
bh_addr_info_t *addr_info,
|
||||||
size_t addr_info_size, size_t *max_info_size);
|
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,
|
__wasi_errno_t
|
||||||
int oflags, mode_t mode);
|
blocking_op_openat(wasm_exec_env_t exec_env, os_file_handle handle,
|
||||||
|
const char *path, __wasi_oflags_t oflags,
|
||||||
|
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
|
||||||
|
wasi_libc_file_access_mode access_mode, os_file_handle *out);
|
|
@ -49,7 +49,7 @@
|
||||||
/* Mutex that uses the lock annotations. */
|
/* Mutex that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE mutex {
|
struct LOCKABLE mutex {
|
||||||
pthread_mutex_t object;
|
korp_mutex object;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
@ -60,69 +60,71 @@ struct LOCKABLE mutex {
|
||||||
static inline bool
|
static inline bool
|
||||||
mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
return pthread_mutex_init(&lock->object, NULL) == 0 ? true : false;
|
return os_mutex_init(&lock->object) == BHT_OK ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&lock->object);
|
os_mutex_destroy(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_lock(struct mutex *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
mutex_lock(struct mutex *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock->object);
|
os_mutex_lock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mutex_unlock(struct mutex *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
mutex_unlock(struct mutex *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&lock->object);
|
os_mutex_unlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read-write lock that uses the lock annotations. */
|
/* Read-write lock that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE rwlock {
|
struct LOCKABLE rwlock {
|
||||||
pthread_rwlock_t object;
|
korp_rwlock object;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
|
rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock)
|
||||||
{
|
{
|
||||||
return pthread_rwlock_init(&lock->object, NULL) == 0 ? true : false;
|
return os_rwlock_init(&lock->object) == 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_rdlock(struct rwlock *lock) LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS
|
rwlock_rdlock(struct rwlock *lock) LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_rdlock(&lock->object);
|
os_rwlock_rdlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_wrlock(struct rwlock *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
rwlock_wrlock(struct rwlock *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_wrlock(&lock->object);
|
os_rwlock_wrlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_unlock(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
rwlock_unlock(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_unlock(&lock->object);
|
os_rwlock_unlock(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rwlock_destroy(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
rwlock_destroy(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_rwlock_destroy(&lock->object);
|
os_rwlock_destroy(&lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Condition variable that uses the lock annotations. */
|
/* Condition variable that uses the lock annotations. */
|
||||||
|
|
||||||
struct LOCKABLE cond {
|
struct LOCKABLE cond {
|
||||||
pthread_cond_t object;
|
korp_cond object;
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
clockid_t clock;
|
clockid_t clock;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -147,43 +149,49 @@ cond_init_monotonic(struct cond *cond)
|
||||||
fail:
|
fail:
|
||||||
pthread_condattr_destroy(&attr);
|
pthread_condattr_destroy(&attr);
|
||||||
#else
|
#else
|
||||||
if (pthread_cond_init(&cond->object, NULL) != 0)
|
if (os_cond_init(&cond->object) != 0)
|
||||||
return false;
|
return false;
|
||||||
ret = true;
|
ret = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
cond->clock = CLOCK_MONOTONIC;
|
cond->clock = CLOCK_MONOTONIC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
cond_init_realtime(struct cond *cond)
|
cond_init_realtime(struct cond *cond)
|
||||||
{
|
{
|
||||||
if (pthread_cond_init(&cond->object, NULL) != 0)
|
if (os_cond_init(&cond->object) != 0)
|
||||||
return false;
|
return false;
|
||||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
|
||||||
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
|
||||||
|
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|
||||||
|
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
|
||||||
cond->clock = CLOCK_REALTIME;
|
cond->clock = CLOCK_REALTIME;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cond_destroy(struct cond *cond)
|
cond_destroy(struct cond *cond)
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&cond->object);
|
os_cond_destroy(&cond->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cond_signal(struct cond *cond)
|
cond_signal(struct cond *cond)
|
||||||
{
|
{
|
||||||
pthread_cond_signal(&cond->object);
|
os_cond_signal(&cond->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_HAS_CLOCK_NANOSLEEP
|
#if !CONFIG_HAS_CLOCK_NANOSLEEP
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
|
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
|
||||||
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
|
@ -259,7 +267,7 @@ static inline void
|
||||||
cond_wait(struct cond *cond, struct mutex *lock)
|
cond_wait(struct cond *cond, struct mutex *lock)
|
||||||
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
pthread_cond_wait(&cond->object, &lock->object);
|
os_cond_wait(&cond->object, &lock->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,8 @@ struct addr_pool {
|
||||||
bool
|
bool
|
||||||
fd_table_init(struct fd_table *);
|
fd_table_init(struct fd_table *);
|
||||||
bool
|
bool
|
||||||
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
|
fd_table_insert_existing(struct fd_table *, __wasi_fd_t, os_file_handle,
|
||||||
|
bool is_stdio);
|
||||||
bool
|
bool
|
||||||
fd_prestats_init(struct fd_prestats *);
|
fd_prestats_init(struct fd_prestats *);
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -47,6 +47,23 @@ random_buf(void *buf, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(BH_PLATFORM_WINDOWS)
|
||||||
|
|
||||||
|
#include <wincrypt.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
random_buf(void *buf, size_t len)
|
||||||
|
{
|
||||||
|
static int crypt_initialized = 0;
|
||||||
|
static HCRYPTPROV provider;
|
||||||
|
if (!crypt_initialized) {
|
||||||
|
CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
||||||
|
CRYPT_VERIFYCONTEXT);
|
||||||
|
crypt_initialized = 1;
|
||||||
|
}
|
||||||
|
CryptGenRandom(provider, len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int urandom;
|
static int urandom;
|
||||||
|
|
|
@ -47,75 +47,19 @@
|
||||||
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
|
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_FDATASYNC 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_FDATASYNC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For NuttX, CONFIG_HAS_ISATTY is provided by its platform header.
|
|
||||||
* (platform_internal.h)
|
|
||||||
*/
|
|
||||||
#ifndef __NuttX__
|
|
||||||
#ifndef __CloudABI__
|
|
||||||
#define CONFIG_HAS_ISATTY 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_ISATTY 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(__COSMOPOLITAN__)
|
|
||||||
#define CONFIG_HAS_POSIX_FALLOCATE 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_POSIX_FALLOCATE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_PREADV 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_PREADV 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__CloudABI__)
|
#if defined(__APPLE__) || defined(__CloudABI__)
|
||||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
|
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
|
||||||
#else
|
#else
|
||||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
|
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \
|
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32) \
|
||||||
&& !defined(__COSMOPOLITAN__)
|
&& !defined(__COSMOPOLITAN__)
|
||||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
|
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
|
||||||
#else
|
#else
|
||||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
|
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(ESP_PLATFORM)
|
|
||||||
#define CONFIG_HAS_PWRITEV 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_PWRITEV 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define st_atim st_atimespec
|
|
||||||
#define st_ctim st_ctimespec
|
|
||||||
#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)
|
#if !defined(BH_PLATFORM_LINUX_SGX)
|
||||||
/* Clang's __GNUC_PREREQ macro has a different meaning than GCC one,
|
/* Clang's __GNUC_PREREQ macro has a different meaning than GCC one,
|
||||||
so we have to handle this case specially */
|
so we have to handle this case specially */
|
||||||
|
@ -143,10 +87,4 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */
|
||||||
#define CONFIG_HAS_STD_ATOMIC 0
|
#define CONFIG_HAS_STD_ATOMIC 0
|
||||||
#endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */
|
#endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */
|
||||||
|
|
||||||
#if !defined(__NuttX__)
|
|
||||||
#define CONFIG_HAS_D_INO 1
|
|
||||||
#else
|
|
||||||
#define CONFIG_HAS_D_INO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1406,3 +1406,19 @@ exception_unlock(WASMModuleInstance *module_inst)
|
||||||
{
|
{
|
||||||
os_mutex_unlock(&_exception_lock);
|
os_mutex_unlock(&_exception_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_lock(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
os_mutex_lock(&cluster->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_unlock(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
os_mutex_unlock(&cluster->lock);
|
||||||
|
}
|
||||||
|
|
|
@ -215,6 +215,12 @@ wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst);
|
||||||
|
|
||||||
#endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
|
#endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_lock(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_cluster_traverse_unlock(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,19 +24,23 @@ hmu_is_in_heap(void *hmu, gc_uint8 *heap_base_addr, gc_uint8 *heap_end_addr)
|
||||||
static bool
|
static bool
|
||||||
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
{
|
{
|
||||||
hmu_tree_node_t *q = NULL, **slot = NULL, *parent;
|
hmu_tree_node_t *q = NULL, **slot = NULL;
|
||||||
hmu_tree_node_t *root = heap->kfc_tree_root;
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
hmu_tree_node_t *root = heap->kfc_tree_root, *parent;
|
||||||
gc_uint8 *base_addr = heap->base_addr;
|
gc_uint8 *base_addr = heap->base_addr;
|
||||||
gc_uint8 *end_addr = base_addr + heap->current_size;
|
gc_uint8 *end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
bh_assert(p);
|
bh_assert(p);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
parent = p->parent;
|
parent = p->parent;
|
||||||
if (!parent || p == root /* p can not be the ROOT node */
|
if (!parent || p == root /* p can not be the ROOT node */
|
||||||
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
|| !hmu_is_in_heap(p, base_addr, end_addr)
|
||||||
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
|| (parent != root && !hmu_is_in_heap(parent, base_addr, end_addr))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the slot which holds pointer to node p */
|
/* get the slot which holds pointer to node p */
|
||||||
if (p == p->parent->right) {
|
if (p == p->parent->right) {
|
||||||
|
@ -67,9 +71,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
/* move right child up*/
|
/* move right child up*/
|
||||||
*slot = p->right;
|
*slot = p->right;
|
||||||
if (p->right) {
|
if (p->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
p->right->parent = p->parent;
|
p->right->parent = p->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +86,11 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
if (!p->right) {
|
if (!p->right) {
|
||||||
/* move left child up*/
|
/* move left child up*/
|
||||||
*slot = p->left;
|
*slot = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* p->left can never be NULL unless it is corrupted. */
|
/* p->left can never be NULL unless it is corrupted. */
|
||||||
p->left->parent = p->parent;
|
p->left->parent = p->parent;
|
||||||
|
|
||||||
|
@ -92,14 +100,18 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
/* both left & right exist, find p's predecessor at first*/
|
/* both left & right exist, find p's predecessor at first*/
|
||||||
q = p->left;
|
q = p->left;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
while (q->right) {
|
while (q->right) {
|
||||||
q = q->right;
|
q = q->right;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove from the tree*/
|
/* remove from the tree*/
|
||||||
|
@ -111,15 +123,19 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
q->left = p->left;
|
q->left = p->left;
|
||||||
q->right = p->right;
|
q->right = p->right;
|
||||||
if (q->left) {
|
if (q->left) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->left, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->left->parent = q;
|
q->left->parent = q;
|
||||||
}
|
}
|
||||||
if (q->right) {
|
if (q->right) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(q->right, base_addr, end_addr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
q->right->parent = q;
|
q->right->parent = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,27 +143,35 @@ remove_tree_node(gc_heap_t *heap, hmu_tree_node_t *p)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
gc_size_t size;
|
gc_size_t size;
|
||||||
|
|
||||||
bh_assert(gci_is_heap_valid(heap));
|
bh_assert(gci_is_heap_valid(heap));
|
||||||
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
bh_assert(hmu && (gc_uint8 *)hmu >= heap->base_addr
|
||||||
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
&& (gc_uint8 *)hmu < heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (hmu_get_ut(hmu) != HMU_FC) {
|
if (hmu_get_ut(hmu) != HMU_FC) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
size = hmu_get_size(hmu);
|
size = hmu_get_size(hmu);
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
|
@ -156,10 +180,12 @@ unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||||
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
hmu_normal_node_t *node = heap->kfc_normal_list[node_idx].next;
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(node, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
node_next = get_hmu_normal_node_next(node);
|
node_next = get_hmu_normal_node_next(node);
|
||||||
if ((hmu_t *)node == hmu) {
|
if ((hmu_t *)node == hmu) {
|
||||||
if (!node_prev) /* list head */
|
if (!node_prev) /* list head */
|
||||||
|
@ -205,7 +231,9 @@ hmu_set_free_size(hmu_t *hmu)
|
||||||
bool
|
bool
|
||||||
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_uint8 *base_addr, *end_addr;
|
gc_uint8 *base_addr, *end_addr;
|
||||||
|
#endif
|
||||||
hmu_normal_node_t *np = NULL;
|
hmu_normal_node_t *np = NULL;
|
||||||
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
||||||
uint32 node_idx;
|
uint32 node_idx;
|
||||||
|
@ -219,8 +247,10 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
<= heap->base_addr + heap->current_size);
|
<= heap->base_addr + heap->current_size);
|
||||||
bh_assert(!(size & 7));
|
bh_assert(!(size & 7));
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
base_addr = heap->base_addr;
|
base_addr = heap->base_addr;
|
||||||
end_addr = base_addr + heap->current_size;
|
end_addr = base_addr + heap->current_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu_set_ut(hmu, HMU_FC);
|
hmu_set_ut(hmu, HMU_FC);
|
||||||
hmu_set_size(hmu, size);
|
hmu_set_size(hmu, size);
|
||||||
|
@ -228,10 +258,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
|
|
||||||
if (HMU_IS_FC_NORMAL(size)) {
|
if (HMU_IS_FC_NORMAL(size)) {
|
||||||
np = (hmu_normal_node_t *)hmu;
|
np = (hmu_normal_node_t *)hmu;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(np, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
node_idx = size >> 3;
|
node_idx = size >> 3;
|
||||||
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
set_hmu_normal_node_next(np, heap->kfc_normal_list[node_idx].next);
|
||||||
|
@ -265,10 +297,12 @@ gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||||
}
|
}
|
||||||
tp = tp->left;
|
tp = tp->left;
|
||||||
}
|
}
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -321,15 +355,19 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(node_idx >= init_node_idx);
|
bh_assert(node_idx >= init_node_idx);
|
||||||
|
|
||||||
p = normal_head->next;
|
p = normal_head->next;
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(p, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
normal_head->next = get_hmu_normal_node_next(p);
|
normal_head->next = get_hmu_normal_node_next(p);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
if (((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) != 0) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
||||||
/* with bigger size*/
|
/* with bigger size*/
|
||||||
|
@ -365,10 +403,12 @@ alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||||
bh_assert(root);
|
bh_assert(root);
|
||||||
tp = root->right;
|
tp = root->right;
|
||||||
while (tp) {
|
while (tp) {
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
if (!hmu_is_in_heap(tp, base_addr, end_addr)) {
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tp->size < size) {
|
if (tp->size < size) {
|
||||||
tp = tp->right;
|
tp = tp->right;
|
||||||
|
@ -462,10 +502,12 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_mutex_lock(&heap->lock);
|
os_mutex_lock(&heap->lock);
|
||||||
|
|
||||||
|
@ -522,10 +564,12 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, const char *file,
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (obj_old) {
|
if (obj_old) {
|
||||||
hmu_old = obj_to_hmu(obj_old);
|
hmu_old = obj_to_hmu(obj_old);
|
||||||
|
@ -647,10 +691,12 @@ gc_free_vo_internal(void *vheap, gc_object_t obj, const char *file, int line)
|
||||||
return GC_SUCCESS;
|
return GC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, free memory failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hmu = obj_to_hmu(obj);
|
hmu = obj_to_hmu(obj);
|
||||||
|
|
||||||
|
@ -767,11 +813,13 @@ gci_dump(gc_heap_t *heap)
|
||||||
else if (ut == HMU_FC)
|
else if (ut == HMU_FC)
|
||||||
inuse = 'F';
|
inuse = 'F';
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
os_printf("#%d %08" PRIx32 " %" PRIx32 " %d %d"
|
||||||
" %c %" PRId32 "\n",
|
" %c %" PRId32 "\n",
|
||||||
|
@ -788,8 +836,12 @@ gci_dump(gc_heap_t *heap)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,9 +271,11 @@ typedef struct gc_heap_struct {
|
||||||
size[left] <= size[cur] < size[right] */
|
size[left] <= size[cur] < size[right] */
|
||||||
hmu_tree_node_t *kfc_tree_root;
|
hmu_tree_node_t *kfc_tree_root;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
/* whether heap is corrupted, e.g. the hmu nodes are modified
|
||||||
by user */
|
by user */
|
||||||
bool is_heap_corrupted;
|
bool is_heap_corrupted;
|
||||||
|
#endif
|
||||||
|
|
||||||
gc_size_t init_size;
|
gc_size_t init_size;
|
||||||
gc_size_t highmark_size;
|
gc_size_t highmark_size;
|
||||||
|
|
|
@ -83,7 +83,9 @@ hmu_verify(void *vheap, hmu_t *hmu)
|
||||||
os_printf("Invalid padding for object created at %s:%d\n",
|
os_printf("Invalid padding for object created at %s:%d\n",
|
||||||
(prefix->file_name ? prefix->file_name : ""),
|
(prefix->file_name ? prefix->file_name : ""),
|
||||||
prefix->line_no);
|
prefix->line_no);
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,8 +133,11 @@ gc_destroy_with_pool(gc_handle_t handle)
|
||||||
hmu_t *cur = (hmu_t *)heap->base_addr;
|
hmu_t *cur = (hmu_t *)heap->base_addr;
|
||||||
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
hmu_t *end = (hmu_t *)((char *)heap->base_addr + heap->current_size);
|
||||||
|
|
||||||
if (!heap->is_heap_corrupted
|
if (
|
||||||
&& (hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
|
!heap->is_heap_corrupted &&
|
||||||
|
#endif
|
||||||
|
(hmu_t *)((char *)cur + hmu_get_size(cur)) != end) {
|
||||||
os_printf("Memory leak detected:\n");
|
os_printf("Memory leak detected:\n");
|
||||||
gci_dump(heap);
|
gci_dump(heap);
|
||||||
ret = GC_ERROR;
|
ret = GC_ERROR;
|
||||||
|
@ -186,10 +189,12 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (heap->is_heap_corrupted) {
|
if (heap->is_heap_corrupted) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
heap->base_addr = (uint8 *)base_addr_new;
|
heap->base_addr = (uint8 *)base_addr_new;
|
||||||
|
|
||||||
|
@ -211,11 +216,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
while (cur < end) {
|
while (cur < end) {
|
||||||
size = hmu_get_size(cur);
|
size = hmu_get_size(cur);
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
||||||
tree_node = (hmu_tree_node_t *)cur;
|
tree_node = (hmu_tree_node_t *)cur;
|
||||||
|
@ -238,11 +245,15 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
cur = (hmu_t *)((char *)cur + size);
|
cur = (hmu_t *)((char *)cur + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return GC_ERROR;
|
return GC_ERROR;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bh_assert(cur == end);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -250,9 +261,13 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
bool
|
bool
|
||||||
gc_is_heap_corrupted(gc_handle_t handle)
|
gc_is_heap_corrupted(gc_handle_t handle)
|
||||||
{
|
{
|
||||||
|
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
|
||||||
gc_heap_t *heap = (gc_heap_t *)handle;
|
gc_heap_t *heap = (gc_heap_t *)handle;
|
||||||
|
|
||||||
return heap->is_heap_corrupted ? true : false;
|
return heap->is_heap_corrupted ? true : false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BH_ENABLE_GC_VERIFY != 0
|
#if BH_ENABLE_GC_VERIFY != 0
|
||||||
|
|
|
@ -10,6 +10,14 @@ if (WAMR_BUILD_GC_VERIFY EQUAL 1)
|
||||||
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
add_definitions (-DBH_ENABLE_GC_VERIFY=1)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED WAMR_BUILD_GC_CORRUPTION_CHECK)
|
||||||
|
set (WAMR_BUILD_GC_CORRUPTION_CHECK 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (WAMR_BUILD_GC_CORRUPTION_CHECK EQUAL 0)
|
||||||
|
add_definitions (-DBH_ENABLE_GC_CORRUPTION_CHECK=0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all
|
file (GLOB_RECURSE source_all
|
||||||
${MEM_ALLOC_DIR}/ems/*.c
|
${MEM_ALLOC_DIR}/ems/*.c
|
||||||
${MEM_ALLOC_DIR}/tlsf/*.c
|
${MEM_ALLOC_DIR}/tlsf/*.c
|
||||||
|
|
|
@ -47,7 +47,7 @@ os_dumps_proc_mem_info(char *out, unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
if ((uint64)size >= UINT32_MAX)
|
if ((uint64)size >= UINT32_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -64,4 +64,14 @@ int signbit(double x);
|
||||||
int isnan(double x);
|
int isnan(double x);
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* end of _BH_PLATFORM_H */
|
#endif /* end of _BH_PLATFORM_H */
|
||||||
|
|
|
@ -56,6 +56,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -145,6 +146,16 @@ preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
||||||
ssize_t
|
ssize_t
|
||||||
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "errno.h"
|
||||||
|
#include "libc_errno.h"
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_errno(int error)
|
||||||
|
{
|
||||||
|
// The C standard library only requires EDOM, EILSEQ and ERANGE to be
|
||||||
|
// defined. Other error codes are POSIX-specific and hence may or may
|
||||||
|
// not be available on non-POSIX platforms.
|
||||||
|
__wasi_errno_t code = __WASI_ENOSYS;
|
||||||
|
#define X(v) \
|
||||||
|
case v: \
|
||||||
|
code = __WASI_##v; \
|
||||||
|
break;
|
||||||
|
switch (error) {
|
||||||
|
X(EDOM)
|
||||||
|
X(EILSEQ)
|
||||||
|
X(ERANGE)
|
||||||
|
#ifdef E2BIG
|
||||||
|
X(E2BIG)
|
||||||
|
#endif
|
||||||
|
#ifdef EACCES
|
||||||
|
X(EACCES)
|
||||||
|
#endif
|
||||||
|
#ifdef EADDRINUSE
|
||||||
|
X(EADDRINUSE)
|
||||||
|
#endif
|
||||||
|
#ifdef EADDRNOTAVAIL
|
||||||
|
X(EADDRNOTAVAIL)
|
||||||
|
#endif
|
||||||
|
#ifdef EAFNOSUPPORT
|
||||||
|
X(EAFNOSUPPORT)
|
||||||
|
#endif
|
||||||
|
#ifdef EAGAIN
|
||||||
|
X(EAGAIN)
|
||||||
|
#endif
|
||||||
|
#ifdef EALREADY
|
||||||
|
X(EALREADY)
|
||||||
|
#endif
|
||||||
|
#ifdef EBADF
|
||||||
|
X(EBADF)
|
||||||
|
#endif
|
||||||
|
#ifdef EBADMSG
|
||||||
|
X(EBADMSG)
|
||||||
|
#endif
|
||||||
|
#ifdef EBUSY
|
||||||
|
X(EBUSY)
|
||||||
|
#endif
|
||||||
|
#ifdef ECANCELED
|
||||||
|
X(ECANCELED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECHILD
|
||||||
|
X(ECHILD)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNABORTED
|
||||||
|
X(ECONNABORTED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNREFUSED
|
||||||
|
X(ECONNREFUSED)
|
||||||
|
#endif
|
||||||
|
#ifdef ECONNRESET
|
||||||
|
X(ECONNRESET)
|
||||||
|
#endif
|
||||||
|
#ifdef EDEADLK
|
||||||
|
X(EDEADLK)
|
||||||
|
#endif
|
||||||
|
#ifdef EDESTADDRREQ
|
||||||
|
X(EDESTADDRREQ)
|
||||||
|
#endif
|
||||||
|
#ifdef EDQUOT
|
||||||
|
X(EDQUOT)
|
||||||
|
#endif
|
||||||
|
#ifdef EEXIST
|
||||||
|
X(EEXIST)
|
||||||
|
#endif
|
||||||
|
#ifdef EFAULT
|
||||||
|
X(EFAULT)
|
||||||
|
#endif
|
||||||
|
#ifdef EFBIG
|
||||||
|
X(EFBIG)
|
||||||
|
#endif
|
||||||
|
#ifdef EHOSTUNREACH
|
||||||
|
X(EHOSTUNREACH)
|
||||||
|
#endif
|
||||||
|
#ifdef EIDRM
|
||||||
|
X(EIDRM)
|
||||||
|
#endif
|
||||||
|
#ifdef EINPROGRESS
|
||||||
|
X(EINPROGRESS)
|
||||||
|
#endif
|
||||||
|
#ifdef EINTR
|
||||||
|
X(EINTR)
|
||||||
|
#endif
|
||||||
|
#ifdef EINVAL
|
||||||
|
X(EINVAL)
|
||||||
|
#endif
|
||||||
|
#ifdef EIO
|
||||||
|
X(EIO)
|
||||||
|
#endif
|
||||||
|
#ifdef EISCONN
|
||||||
|
X(EISCONN)
|
||||||
|
#endif
|
||||||
|
#ifdef EISDIR
|
||||||
|
X(EISDIR)
|
||||||
|
#endif
|
||||||
|
#ifdef ELOOP
|
||||||
|
X(ELOOP)
|
||||||
|
#endif
|
||||||
|
#ifdef EMFILE
|
||||||
|
X(EMFILE)
|
||||||
|
#endif
|
||||||
|
#ifdef EMLINK
|
||||||
|
X(EMLINK)
|
||||||
|
#endif
|
||||||
|
#ifdef EMSGSIZE
|
||||||
|
X(EMSGSIZE)
|
||||||
|
#endif
|
||||||
|
#ifdef EMULTIHOP
|
||||||
|
X(EMULTIHOP)
|
||||||
|
#endif
|
||||||
|
#ifdef ENAMETOOLONG
|
||||||
|
X(ENAMETOOLONG)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETDOWN
|
||||||
|
X(ENETDOWN)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETRESET
|
||||||
|
X(ENETRESET)
|
||||||
|
#endif
|
||||||
|
#ifdef ENETUNREACH
|
||||||
|
X(ENETUNREACH)
|
||||||
|
#endif
|
||||||
|
#ifdef ENFILE
|
||||||
|
X(ENFILE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOBUFS
|
||||||
|
X(ENOBUFS)
|
||||||
|
#endif
|
||||||
|
#ifdef ENODEV
|
||||||
|
X(ENODEV)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOENT
|
||||||
|
X(ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOEXEC
|
||||||
|
X(ENOEXEC)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOLCK
|
||||||
|
X(ENOLCK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOLINK
|
||||||
|
X(ENOLINK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOMEM
|
||||||
|
X(ENOMEM)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOMSG
|
||||||
|
X(ENOMSG)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOPROTOOPT
|
||||||
|
X(ENOPROTOOPT)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOSPC
|
||||||
|
X(ENOSPC)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOSYS
|
||||||
|
X(ENOSYS)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTCAPABLE
|
||||||
|
X(ENOTCAPABLE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTCONN
|
||||||
|
X(ENOTCONN)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTDIR
|
||||||
|
X(ENOTDIR)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTEMPTY
|
||||||
|
X(ENOTEMPTY)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTRECOVERABLE
|
||||||
|
X(ENOTRECOVERABLE)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTSOCK
|
||||||
|
X(ENOTSOCK)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTSUP
|
||||||
|
X(ENOTSUP)
|
||||||
|
#endif
|
||||||
|
#ifdef ENOTTY
|
||||||
|
X(ENOTTY)
|
||||||
|
#endif
|
||||||
|
#ifdef ENXIO
|
||||||
|
X(ENXIO)
|
||||||
|
#endif
|
||||||
|
#ifdef EOVERFLOW
|
||||||
|
X(EOVERFLOW)
|
||||||
|
#endif
|
||||||
|
#ifdef EOWNERDEAD
|
||||||
|
X(EOWNERDEAD)
|
||||||
|
#endif
|
||||||
|
#ifdef EPERM
|
||||||
|
X(EPERM)
|
||||||
|
#endif
|
||||||
|
#ifdef EPIPE
|
||||||
|
X(EPIPE)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTO
|
||||||
|
X(EPROTO)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTONOSUPPORT
|
||||||
|
X(EPROTONOSUPPORT)
|
||||||
|
#endif
|
||||||
|
#ifdef EPROTOTYPE
|
||||||
|
X(EPROTOTYPE)
|
||||||
|
#endif
|
||||||
|
#ifdef EROFS
|
||||||
|
X(EROFS)
|
||||||
|
#endif
|
||||||
|
#ifdef ESPIPE
|
||||||
|
X(ESPIPE)
|
||||||
|
#endif
|
||||||
|
#ifdef ESRCH
|
||||||
|
X(ESRCH)
|
||||||
|
#endif
|
||||||
|
#ifdef ESTALE
|
||||||
|
X(ESTALE)
|
||||||
|
#endif
|
||||||
|
#ifdef ETIMEDOUT
|
||||||
|
X(ETIMEDOUT)
|
||||||
|
#endif
|
||||||
|
#ifdef ETXTBSY
|
||||||
|
X(ETXTBSY)
|
||||||
|
#endif
|
||||||
|
#ifdef EXDEV
|
||||||
|
X(EXDEV)
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
#ifdef EOPNOTSUPP
|
||||||
|
if (error == EOPNOTSUPP)
|
||||||
|
code = __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
#ifdef EWOULDBLOCK
|
||||||
|
if (error == EWOULDBLOCK)
|
||||||
|
code = __WASI_EAGAIN;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef X
|
||||||
|
return code;
|
||||||
|
}
|
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WASI_ERRNO_H
|
||||||
|
#define WASI_ERRNO_H
|
||||||
|
|
||||||
|
#include "platform_wasi_types.h"
|
||||||
|
|
||||||
|
// Converts an errno error code to a WASI error code.
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_errno(int error);
|
||||||
|
|
||||||
|
#endif /* end of WASI_ERRNO_H */
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
set (PLATFORM_COMMON_LIBC_UTIL_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
include_directories(${PLATFORM_COMMON_LIBC_UTIL_DIR})
|
||||||
|
|
||||||
|
file (GLOB_RECURSE PLATFORM_COMMON_LIBC_UTIL_SOURCE ${PLATFORM_COMMON_LIBC_UTIL_DIR}/*.c)
|
|
@ -5,4 +5,14 @@ set (PLATFORM_COMMON_POSIX_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
|
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
|
||||||
|
|
||||||
|
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
list(REMOVE_ITEM source_all
|
||||||
|
${PLATFORM_COMMON_POSIX_DIR}/posix_file.c
|
||||||
|
${PLATFORM_COMMON_POSIX_DIR}/posix_clock.c
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
include (${CMAKE_CURRENT_LIST_DIR}/../libc-util/platform_common_libc_util.cmake)
|
||||||
|
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||||
|
endif()
|
||||||
|
|
||||||
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )
|
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )
|
||||||
|
|
86
core/shared/platform/common/posix/posix_clock.c
Normal file
86
core/shared/platform/common/posix/posix_clock.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libc_errno.h"
|
||||||
|
#include "platform_api_extension.h"
|
||||||
|
|
||||||
|
#define NANOSECONDS_PER_SECOND 1000000000ULL
|
||||||
|
|
||||||
|
static __wasi_errno_t
|
||||||
|
wasi_clockid_to_clockid(__wasi_clockid_t in, clockid_t *out)
|
||||||
|
{
|
||||||
|
switch (in) {
|
||||||
|
case __WASI_CLOCK_MONOTONIC:
|
||||||
|
*out = CLOCK_MONOTONIC;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
case __WASI_CLOCK_REALTIME:
|
||||||
|
*out = CLOCK_REALTIME;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||||
|
#if defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||||
|
*out = CLOCK_PROCESS_CPUTIME_ID;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
#else
|
||||||
|
return __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||||
|
#if defined(CLOCK_THREAD_CPUTIME_ID)
|
||||||
|
*out = CLOCK_THREAD_CPUTIME_ID;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
#else
|
||||||
|
return __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __wasi_timestamp_t
|
||||||
|
timespec_to_nanoseconds(const struct timespec *ts)
|
||||||
|
{
|
||||||
|
if (ts->tv_sec < 0)
|
||||||
|
return 0;
|
||||||
|
if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / NANOSECONDS_PER_SECOND)
|
||||||
|
return UINT64_MAX;
|
||||||
|
return (__wasi_timestamp_t)ts->tv_sec * NANOSECONDS_PER_SECOND
|
||||||
|
+ (__wasi_timestamp_t)ts->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
|
||||||
|
{
|
||||||
|
clockid_t nclock_id;
|
||||||
|
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_getres(nclock_id, &ts) < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
*resolution = timespec_to_nanoseconds(&ts);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||||
|
__wasi_timestamp_t *time)
|
||||||
|
{
|
||||||
|
clockid_t nclock_id;
|
||||||
|
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_gettime(nclock_id, &ts) < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
*time = timespec_to_nanoseconds(&ts);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
1007
core/shared/platform/common/posix/posix_file.c
Normal file
1007
core/shared/platform/common/posix/posix_file.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@ round_down(uintptr_t v, uintptr_t b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
int map_prot = PROT_NONE;
|
int map_prot = PROT_NONE;
|
||||||
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
||||||
|
@ -114,7 +114,7 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
||||||
/* try 10 times, step with 1MB each time */
|
/* try 10 times, step with 1MB each time */
|
||||||
for (i = 0; i < 10 && hint_addr < (uint8 *)(uintptr_t)(2ULL * BH_GB);
|
for (i = 0; i < 10 && hint_addr < (uint8 *)(uintptr_t)(2ULL * BH_GB);
|
||||||
i++) {
|
i++) {
|
||||||
addr = mmap(hint_addr, request_size, map_prot, map_flags, -1, 0);
|
addr = mmap(hint_addr, request_size, map_prot, map_flags, file, 0);
|
||||||
if (addr != MAP_FAILED) {
|
if (addr != MAP_FAILED) {
|
||||||
if (addr > (uint8 *)(uintptr_t)(2ULL * BH_GB)) {
|
if (addr > (uint8 *)(uintptr_t)(2ULL * BH_GB)) {
|
||||||
/* unmap and try again if the mapped address doesn't
|
/* unmap and try again if the mapped address doesn't
|
||||||
|
@ -136,7 +136,7 @@ os_mmap(void *hint, size_t size, int prot, int flags)
|
||||||
if (addr == MAP_FAILED) {
|
if (addr == MAP_FAILED) {
|
||||||
/* try 5 times */
|
/* try 5 times */
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
|
addr = mmap(hint, request_size, map_prot, map_flags, file, 0);
|
||||||
if (addr != MAP_FAILED)
|
if (addr != MAP_FAILED)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -266,4 +266,4 @@ os_icache_flush(void *start, size_t len)
|
||||||
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
|
||||||
sys_icache_invalidate(start, len);
|
sys_icache_invalidate(start, len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,61 @@ os_cond_broadcast(korp_cond *cond)
|
||||||
return BHT_OK;
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_init(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_init(lock, NULL) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_rdlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_rdlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_wrlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_wrlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_unlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_unlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_destroy(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_destroy(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_thread_join(korp_tid thread, void **value_ptr)
|
os_thread_join(korp_tid thread, void **value_ptr)
|
||||||
{
|
{
|
||||||
|
@ -609,7 +664,7 @@ os_thread_signal_init(os_signal_handler handler)
|
||||||
|
|
||||||
/* Initialize memory for signal alternate stack of current thread */
|
/* Initialize memory for signal alternate stack of current thread */
|
||||||
if (!(map_addr = os_mmap(NULL, map_size, MMAP_PROT_READ | MMAP_PROT_WRITE,
|
if (!(map_addr = os_mmap(NULL, map_size, MMAP_PROT_READ | MMAP_PROT_WRITE,
|
||||||
MMAP_MAP_NONE))) {
|
MMAP_MAP_NONE, os_get_invalid_handle()))) {
|
||||||
os_printf("Failed to mmap memory for alternate stack\n");
|
os_printf("Failed to mmap memory for alternate stack\n");
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,10 @@ typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define bh_socket_t int
|
#define bh_socket_t int
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
#if WASM_DISABLE_WRITE_GS_BASE == 0
|
#if WASM_DISABLE_WRITE_GS_BASE == 0
|
||||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
#define os_writegsbase(base_addr) \
|
#define os_writegsbase(base_addr) \
|
||||||
|
|
|
@ -58,6 +58,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -108,6 +109,16 @@ os_sigreturn();
|
||||||
void
|
void
|
||||||
os_set_signal_number_for_blocking_op(int signo);
|
os_set_signal_number_for_blocking_op(int signo);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,7 @@ static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
if (prot & MMAP_PROT_EXEC) {
|
if (prot & MMAP_PROT_EXEC) {
|
||||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef unsigned int korp_sem;
|
typedef unsigned int korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -108,6 +109,16 @@ typedef unsigned int korp_sem;
|
||||||
#define DT_LNK DTYPE_LINK
|
#define DT_LNK DTYPE_LINK
|
||||||
#define DT_SOCK DTYPE_SOCK
|
#define DT_SOCK DTYPE_SOCK
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,6 +57,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -65,6 +66,10 @@ typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define bh_socket_t int
|
#define bh_socket_t int
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
||||||
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|
||||||
|
@ -107,6 +112,14 @@ os_sigreturn();
|
||||||
void
|
void
|
||||||
os_set_signal_number_for_blocking_op(int signo);
|
os_set_signal_number_for_blocking_op(int signo);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define PLATFORM_API_EXTENSION_H
|
#define PLATFORM_API_EXTENSION_H
|
||||||
|
|
||||||
#include "platform_common.h"
|
#include "platform_common.h"
|
||||||
|
#include "platform_wasi_types.h"
|
||||||
/**
|
/**
|
||||||
* The related data structures should be defined
|
* The related data structures should be defined
|
||||||
* in platform_internal.h
|
* in platform_internal.h
|
||||||
|
@ -238,6 +239,56 @@ os_cond_signal(korp_cond *cond);
|
||||||
int
|
int
|
||||||
os_cond_broadcast(korp_cond *cond);
|
os_cond_broadcast(korp_cond *cond);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize readwrite lock object
|
||||||
|
*
|
||||||
|
* @param cond [OUTPUT] pointer to a lock object variable
|
||||||
|
*
|
||||||
|
* @return 0 if success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_rwlock_init(korp_rwlock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire the read lock
|
||||||
|
*
|
||||||
|
* @param lock lock variable
|
||||||
|
*
|
||||||
|
* @return 0 if success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_rwlock_rdlock(korp_rwlock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire the write lock
|
||||||
|
*
|
||||||
|
* @param lock lock variable
|
||||||
|
*
|
||||||
|
* @return 0 if success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_rwlock_wrlock(korp_rwlock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlocks the lock object
|
||||||
|
*
|
||||||
|
* @param lock lock variable
|
||||||
|
*
|
||||||
|
* @return 0 if success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_rwlock_unlock(korp_rwlock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a lock object
|
||||||
|
*
|
||||||
|
* @param lock lock variable
|
||||||
|
*
|
||||||
|
* @return 0 if success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
os_rwlock_destroy(korp_rwlock *lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new POSIX-like semaphore or opens an existing
|
* Creates a new POSIX-like semaphore or opens an existing
|
||||||
* semaphore. The semaphore is identified by name. For details of
|
* semaphore. The semaphore is identified by name. For details of
|
||||||
|
@ -1061,6 +1112,526 @@ os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled);
|
||||||
int
|
int
|
||||||
os_dumps_proc_mem_info(char *out, unsigned int size);
|
os_dumps_proc_mem_info(char *out, unsigned int size);
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
* Section 3 *
|
||||||
|
* Filesystem support *
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTES:
|
||||||
|
* Fileystem APIs are required for WASI libc support. If you don't need to
|
||||||
|
* support WASI libc, there is no need to implement these APIs. With a
|
||||||
|
* few exceptions, each filesystem function has been named after the equivalent
|
||||||
|
* POSIX filesystem function with an os_ prefix.
|
||||||
|
*
|
||||||
|
* Filesystem types
|
||||||
|
*
|
||||||
|
* os_raw_file_handle: the underlying OS file handle type e.g. int on POSIX
|
||||||
|
* systems and HANDLE on Windows. This type exists to allow embedders to provide
|
||||||
|
* custom file handles for stdout/stdin/stderr.
|
||||||
|
*
|
||||||
|
* os_file_handle: the file handle type used in the WASI libc fd
|
||||||
|
* table. Filesystem implementations can use it as a means to store any
|
||||||
|
* necessary platform-specific information which may not be directly available
|
||||||
|
* through the raw OS file handle. Similiar to POSIX file descriptors, file
|
||||||
|
* handles may also refer to sockets, directories, symbolic links or character
|
||||||
|
* devices and any of the filesystem operations which make sense for these
|
||||||
|
* resource types should be supported as far as possible.
|
||||||
|
*
|
||||||
|
* os_dir_stream: a directory stream type in which fileystem implementations
|
||||||
|
* can store any necessary state to iterate over the entries in a directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about an open file associated with the given handle.
|
||||||
|
*
|
||||||
|
* @param handle the handle for which to obtain file information
|
||||||
|
* @param buf a buffer in which to store the information
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fstat(os_file_handle handle, struct __wasi_filestat_t *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about an open file or directory.
|
||||||
|
* @param handle the directory handle from which to resolve the file/directory
|
||||||
|
* path
|
||||||
|
* @param path the relative path of the file or directory for which to obtain
|
||||||
|
* information
|
||||||
|
* @param buf a buffer in which to store the information
|
||||||
|
* @param follow_symlink whether to follow symlinks when resolving the path
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fstatat(os_file_handle handle, const char *path,
|
||||||
|
struct __wasi_filestat_t *buf, __wasi_lookupflags_t lookup_flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the file status flags for the provided handle. This is similiar to the
|
||||||
|
* POSIX function fcntl called with the F_GETFL command.
|
||||||
|
*
|
||||||
|
* @param handle the handle for which to obtain the file status flags
|
||||||
|
* @param flags a pointer in which to store the output
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_file_get_fdflags(os_file_handle handle, __wasi_fdflags_t *flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file status flags for the provided handle. This is similiar to the
|
||||||
|
* POSIX function fcntl called with the F_SETFL command.
|
||||||
|
*
|
||||||
|
* @param handle the handle for which to set the file status flags
|
||||||
|
* @param flags the flags to set
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_file_set_fdflags(os_file_handle handle, __wasi_fdflags_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronize the data of a file to disk.
|
||||||
|
*
|
||||||
|
* @param handle
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fdatasync(os_file_handle handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronize the data and metadata of a file to disk.
|
||||||
|
*
|
||||||
|
* @param handle
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fsync(os_file_handle handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a preopen directory. The path provided must refer to a directory and the
|
||||||
|
* returned handle will allow only readonly operations.
|
||||||
|
*
|
||||||
|
* @param path the path of the preopen directory to open
|
||||||
|
* @param out a pointer in which to store the newly opened handle
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_open_preopendir(const char *path, os_file_handle *out);
|
||||||
|
|
||||||
|
typedef uint8 wasi_libc_file_access_mode;
|
||||||
|
#define WASI_LIBC_ACCESS_MODE_READ_ONLY 0
|
||||||
|
#define WASI_LIBC_ACCESS_MODE_WRITE_ONLY 1
|
||||||
|
#define WASI_LIBC_ACCESS_MODE_READ_WRITE 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file or directory at the given path.
|
||||||
|
*
|
||||||
|
* @param handle a handle to the directory in which to open the new file or
|
||||||
|
* directory
|
||||||
|
* @param path the relative path of the file or directory to open
|
||||||
|
* @param oflags the flags to determine how the file or directory is opened
|
||||||
|
* @param fd_flags the flags to set on the returned handle
|
||||||
|
* @param lookup_flags whether to follow symlinks when resolving the path
|
||||||
|
* @param access_mode whether the file is opened as read only, write only or
|
||||||
|
* both
|
||||||
|
* @param out a pointer in which to store the newly opened handle
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_openat(os_file_handle handle, const char *path, __wasi_oflags_t oflags,
|
||||||
|
__wasi_fdflags_t fd_flags, __wasi_lookupflags_t lookup_flags,
|
||||||
|
wasi_libc_file_access_mode access_mode, os_file_handle *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the file access mode for the provided handle. This is similiar to the
|
||||||
|
* POSIX function fcntl called with the F_GETFL command combined with the
|
||||||
|
* O_ACCMODE mask.
|
||||||
|
*
|
||||||
|
* @param handle the handle for which to obtain the access mode
|
||||||
|
* @param access_mode a pointer in which to store the access mode
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_file_get_access_mode(os_file_handle handle,
|
||||||
|
wasi_libc_file_access_mode *access_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the provided handle. If is_stdio is true, the raw file handle
|
||||||
|
* associated with the given file handle will not be closed.
|
||||||
|
*
|
||||||
|
* @param handle the handle to close
|
||||||
|
* @param is_stdio whether the provided handle refers to a stdio device
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_close(os_file_handle handle, bool is_stdio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from the provided handle at the given offset into multiple buffers.
|
||||||
|
*
|
||||||
|
* @param handle the handle to read from
|
||||||
|
* @param iov the buffers to read into
|
||||||
|
* @param iovcnt the number of buffers to read into
|
||||||
|
* @param offset the offset to read from
|
||||||
|
* @param nread a pointer in which to store the number of bytes read
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_preadv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
|
__wasi_filesize_t offset, size_t *nread);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data from multiple buffers at the given offset to the provided handle.
|
||||||
|
*
|
||||||
|
* @param handle the handle to write to
|
||||||
|
* @param iov the buffers to write from
|
||||||
|
* @param iovcnt the number of buffers to write from
|
||||||
|
* @param offset the offset to write from
|
||||||
|
* @param nwritten a pointer in which to store the number of bytes written
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_pwritev(os_file_handle handle, const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
|
__wasi_filesize_t offset, size_t *nwritten);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from the provided handle into multiple buffers.
|
||||||
|
*
|
||||||
|
* @param handle the handle to read from
|
||||||
|
* @param iov the buffers to read into
|
||||||
|
* @param iovcnt the number of buffers to read into
|
||||||
|
* @param nread a pointer in which to store the number of bytes read
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_readv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
|
||||||
|
size_t *nread);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data from multiple buffers to the provided handle.
|
||||||
|
*
|
||||||
|
* @param handle the handle to write to
|
||||||
|
* @param iov the buffers to write from
|
||||||
|
* @param iovcnt the number of buffers to write from
|
||||||
|
* @param nwritten a pointer in which to store the number of bytes written
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_writev(os_file_handle handle, const struct __wasi_ciovec_t *iov, int iovcnt,
|
||||||
|
size_t *nwritten);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate storage space for the file associated with the provided handle. This
|
||||||
|
* is similar to the POSIX function posix_fallocate.
|
||||||
|
*
|
||||||
|
* @param handle the handle to allocate space for
|
||||||
|
* @param offset the offset to allocate space at
|
||||||
|
* @param length the amount of space to allocate
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fallocate(os_file_handle handle, __wasi_filesize_t offset,
|
||||||
|
__wasi_filesize_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the size of an open file.
|
||||||
|
*
|
||||||
|
* @param handle the associated file handle for which to adjust the size
|
||||||
|
* @param size the new size of the file
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_ftruncate(os_file_handle handle, __wasi_filesize_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set file access and modification times on an open file or directory.
|
||||||
|
*
|
||||||
|
* @param handle the associated file handle for which to adjust the
|
||||||
|
* access/modification times
|
||||||
|
* @param access_time the timestamp for the new access time
|
||||||
|
* @param modification_time the timestamp for the new modification time
|
||||||
|
* @param fstflags a bitmask to indicate which timestamps to adjust
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_futimens(os_file_handle handle, __wasi_timestamp_t access_time,
|
||||||
|
__wasi_timestamp_t modification_time, __wasi_fstflags_t fstflags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set file access and modification times on an open file or directory.
|
||||||
|
*
|
||||||
|
* @param handle the directory handle from which to resolve the path
|
||||||
|
* @param path the relative path of the file or directory for which to adjust
|
||||||
|
* the access/modification times
|
||||||
|
* @param access_time the timestamp for the new access time
|
||||||
|
* @param modification_time the timestamp for the new modification time
|
||||||
|
* @param fstflags a bitmask to indicate which timestamps to adjust
|
||||||
|
* @param lookup_flags whether to follow symlinks when resolving the path
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_utimensat(os_file_handle handle, const char *path,
|
||||||
|
__wasi_timestamp_t access_time,
|
||||||
|
__wasi_timestamp_t modification_time, __wasi_fstflags_t fstflags,
|
||||||
|
__wasi_lookupflags_t lookup_flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the contents of a symbolic link relative to the provided directory
|
||||||
|
* handle.
|
||||||
|
*
|
||||||
|
* @param handle the directory handle
|
||||||
|
* @param path the relative path of the symbolic link from which to read
|
||||||
|
* @param buf the buffer to read the link contents into
|
||||||
|
* @param bufsize the size of the provided buffer
|
||||||
|
* @param nread a pointer in which to store the number of bytes read into the
|
||||||
|
* buffer
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_readlinkat(os_file_handle handle, const char *path, char *buf,
|
||||||
|
size_t bufsize, size_t *nread);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a link from one path to another path.
|
||||||
|
*
|
||||||
|
* @param from_handle the directory handle from which to resolve the origin path
|
||||||
|
* @param from_path the origin path to link from
|
||||||
|
* @param to_handle the directory handle from which to resolve the destination
|
||||||
|
* path
|
||||||
|
* @param to_path the destination path at which to create the link
|
||||||
|
* @param lookup_flags whether to follow symlinks when resolving the origin path
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_linkat(os_file_handle from_handle, const char *from_path,
|
||||||
|
os_file_handle to_handle, const char *to_path,
|
||||||
|
__wasi_lookupflags_t lookup_flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a symbolic link from one path to another path.
|
||||||
|
*
|
||||||
|
* @param old_path the symbolic link contents
|
||||||
|
* @param handle the directory handle from which to resolve the destination path
|
||||||
|
* @param new_path the destination path at which to create the symbolic link
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_symlinkat(const char *old_path, os_file_handle handle, const char *new_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a directory relative to the provided directory handle.
|
||||||
|
*
|
||||||
|
* @param handle the directory handle
|
||||||
|
* @param path the relative path of the directory to create
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_mkdirat(os_file_handle handle, const char *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename a file or directory.
|
||||||
|
*
|
||||||
|
* @param old_handle the directory handle from which to resolve the old path
|
||||||
|
* @param old_path the source path to rename
|
||||||
|
* @param new_handle the directory handle from which to resolve the destination
|
||||||
|
* path
|
||||||
|
* @param new_path the destination path to which to rename the file or directory
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_renameat(os_file_handle old_handle, const char *old_path,
|
||||||
|
os_file_handle new_handle, const char *new_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink a file or directory.
|
||||||
|
*
|
||||||
|
* @param handle the directory handle from which to resolve the path
|
||||||
|
* @param path the relative path of the file or directory to unlink
|
||||||
|
* @param is_dir whether the provided handle refers to a directory or file
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_unlinkat(os_file_handle handle, const char *path, bool is_dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the read/write offset of an open file.
|
||||||
|
*
|
||||||
|
* @param handle the associated file handle for which to adjust the offset
|
||||||
|
* @param offset the number of bytes to adjust the offset by
|
||||||
|
* @param whence the position whence to adjust the offset
|
||||||
|
* @param new_offset a pointer in which to store the new offset
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_lseek(os_file_handle handle, __wasi_filedelta_t offset,
|
||||||
|
__wasi_whence_t whence, __wasi_filesize_t *new_offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide file advisory information for the given handle. This is similar to
|
||||||
|
* the POSIX function posix_fadvise.
|
||||||
|
*
|
||||||
|
* @param handle the associated file handle for which to provide advisory
|
||||||
|
* information
|
||||||
|
* @param offset the offset within the file to which the advisory
|
||||||
|
* information applies
|
||||||
|
* @param length the length of the region for which the advisory information
|
||||||
|
* applies
|
||||||
|
* @param advice the advice to provide
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fadvise(os_file_handle handle, __wasi_filesize_t offset,
|
||||||
|
__wasi_filesize_t length, __wasi_advice_t advice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given handle refers to a terminal device. __WASI_ESUCCESS
|
||||||
|
* will be returned if the handle is associated with a terminal device,
|
||||||
|
* otherwise an appropriate error code will be returned.
|
||||||
|
*
|
||||||
|
* @param handle
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_isatty(os_file_handle handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a raw file handle to STDIN to a corresponding file handle to STDIN.
|
||||||
|
* If the provided raw file handle is invalid, the platform-default raw handle
|
||||||
|
* for STDIN will be used.
|
||||||
|
*
|
||||||
|
* @param raw_stdin a raw file handle to STDIN
|
||||||
|
*
|
||||||
|
* @return a handle to STDIN
|
||||||
|
*/
|
||||||
|
os_file_handle
|
||||||
|
os_convert_stdin_handle(os_raw_file_handle raw_stdin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a raw file handle to STDOUT to a correponding file handle to STDOUT.
|
||||||
|
* If the provided raw file handle is invalid, the platform-default raw handle
|
||||||
|
* for STDOUT will be used.
|
||||||
|
*
|
||||||
|
* @param raw_stdout a raw file handle to STDOUT
|
||||||
|
*
|
||||||
|
* @return a handle to STDOUT
|
||||||
|
*/
|
||||||
|
os_file_handle
|
||||||
|
os_convert_stdout_handle(os_raw_file_handle raw_stdout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a raw file handle to STDERR to a correponding file handle to STDERR.
|
||||||
|
* If the provided raw file handle is invalid, the platform-default raw handle
|
||||||
|
* for STDERR will be used.
|
||||||
|
*
|
||||||
|
* @param raw_stderr a raw file handle to STDERR
|
||||||
|
*
|
||||||
|
* @return a handle to STDERR
|
||||||
|
*/
|
||||||
|
os_file_handle
|
||||||
|
os_convert_stderr_handle(os_raw_file_handle raw_stderr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a directory stream for the provided directory handle. The returned
|
||||||
|
* directory stream will be positioned at the first entry in the directory.
|
||||||
|
*
|
||||||
|
* @param handle the directory handle
|
||||||
|
* @param dir_stream a pointer in which to store the new directory stream
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_fdopendir(os_file_handle handle, os_dir_stream *dir_stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the position of a directory stream to the beginning of the directory.
|
||||||
|
*
|
||||||
|
* @param dir_stream the directory stream for which to reset the position
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_rewinddir(os_dir_stream dir_stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the position of the given directory stream.
|
||||||
|
*
|
||||||
|
* @param dir_stream the directory stream for which to set the position
|
||||||
|
* @param position the position to set
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_seekdir(os_dir_stream dir_stream, __wasi_dircookie_t position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a directory entry from the given directory stream. The directory name
|
||||||
|
* will be NULL if the end of the directory is reached or an error is
|
||||||
|
* encountered.
|
||||||
|
*
|
||||||
|
* @param dir_stream the directory stream from which to read the entry
|
||||||
|
* @param entry a pointer in which to store the directory entry
|
||||||
|
* @param d_name a pointer in which to store the directory entry name
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_readdir(os_dir_stream dir_stream, __wasi_dirent_t *entry,
|
||||||
|
const char **d_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the given directory stream. The handle associated with the directory
|
||||||
|
* stream will also be closed.
|
||||||
|
*
|
||||||
|
* @param dir_stream the directory stream to close
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_closedir(os_dir_stream dir_stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an invalid directory stream that is guaranteed to cause failure when
|
||||||
|
* called with any directory filesystem operation.
|
||||||
|
*
|
||||||
|
* @return the invalid directory stream
|
||||||
|
*/
|
||||||
|
os_dir_stream
|
||||||
|
os_get_invalid_dir_stream();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given directory stream is valid. An invalid directory
|
||||||
|
* stream is guaranteed to cause failure when called with any directory
|
||||||
|
* filesystem operation.
|
||||||
|
*
|
||||||
|
* @param dir_stream a pointer to a directory stream
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
os_is_dir_stream_valid(os_dir_stream *dir_stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an invalid handle that is guaranteed to cause failure when
|
||||||
|
* called with any filesystem operation.
|
||||||
|
*
|
||||||
|
* @return the invalid handle
|
||||||
|
*/
|
||||||
|
os_file_handle
|
||||||
|
os_get_invalid_handle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given file handle is valid. An invalid handle is
|
||||||
|
* guaranteed to cause failure when called with any filesystem operation.
|
||||||
|
*
|
||||||
|
* @param handle a pointer to a file handle
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
os_is_handle_valid(os_file_handle *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a pathname. The generated pathname will be stored as a
|
||||||
|
* null-terminated string, with a maximum length of PATH_MAX bytes.
|
||||||
|
*
|
||||||
|
* @param path the path to resolve
|
||||||
|
* @param resolved_path the buffer to store the resolved path in
|
||||||
|
*
|
||||||
|
* @return the resolved path if success, NULL otherwise
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
os_realpath(const char *path, char *resolved_path);
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
* Section 4 *
|
||||||
|
* Clock functions *
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTES:
|
||||||
|
* Clock functions are required for WASI libc support. If you don't need to
|
||||||
|
* support WASI libc, there is no need to implement these APIs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the resolution of the specified clock.
|
||||||
|
*
|
||||||
|
* @param clock_id clock identifier
|
||||||
|
* @param resolution output variable to store the clock resolution
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current time of the specified clock.
|
||||||
|
*
|
||||||
|
* @param clock_id clock identifier
|
||||||
|
* @param precision the maximum lag that the returned time value may have,
|
||||||
|
* compared to its actual value.
|
||||||
|
* @param time output variable to store the clock time
|
||||||
|
*/
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||||
|
__wasi_timestamp_t *time);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -130,7 +130,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags);
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file);
|
||||||
void
|
void
|
||||||
os_munmap(void *addr, size_t size);
|
os_munmap(void *addr, size_t size);
|
||||||
int
|
int
|
||||||
|
|
610
core/shared/platform/include/platform_wasi_types.h
Normal file
610
core/shared/platform/include/platform_wasi_types.h
Normal file
|
@ -0,0 +1,610 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file declares the WASI interface. The definitions of types, macros and
|
||||||
|
* structures in this file should be consistent with those in wasi-libc:
|
||||||
|
* https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/headers/public/wasi/api.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLATFORM_WASI_TYPES_H
|
||||||
|
#define _PLATFORM_WASI_TYPES_H
|
||||||
|
|
||||||
|
#include "../../../config.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#ifndef _Static_assert
|
||||||
|
#define _Static_assert static_assert
|
||||||
|
#endif /* _Static_assert */
|
||||||
|
|
||||||
|
#ifndef _Alignof
|
||||||
|
#define _Alignof alignof
|
||||||
|
#endif /* _Alignof */
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* There is no need to check the WASI layout if we're using uvwasi or libc-wasi
|
||||||
|
* is not enabled at all. */
|
||||||
|
#if WASM_ENABLE_UVWASI != 0 || WASM_ENABLE_LIBC_WASI == 0
|
||||||
|
#define assert_wasi_layout(expr, message) /* nothing */
|
||||||
|
#else
|
||||||
|
#define assert_wasi_layout(expr, message) _Static_assert(expr, message)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert_wasi_layout(_Alignof(int8_t) == 1, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(uint8_t) == 1, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(int16_t) == 2, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(uint16_t) == 2, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(int32_t) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(uint32_t) == 4, "non-wasi data layout");
|
||||||
|
#if 0
|
||||||
|
assert_wasi_layout(_Alignof(int64_t) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(uint64_t) == 8, "non-wasi data layout");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_size_t;
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_size_t) == 4, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_advice_t;
|
||||||
|
#define __WASI_ADVICE_NORMAL (0)
|
||||||
|
#define __WASI_ADVICE_SEQUENTIAL (1)
|
||||||
|
#define __WASI_ADVICE_RANDOM (2)
|
||||||
|
#define __WASI_ADVICE_WILLNEED (3)
|
||||||
|
#define __WASI_ADVICE_DONTNEED (4)
|
||||||
|
#define __WASI_ADVICE_NOREUSE (5)
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_clockid_t;
|
||||||
|
#define __WASI_CLOCK_REALTIME (0)
|
||||||
|
#define __WASI_CLOCK_MONOTONIC (1)
|
||||||
|
#define __WASI_CLOCK_PROCESS_CPUTIME_ID (2)
|
||||||
|
#define __WASI_CLOCK_THREAD_CPUTIME_ID (3)
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_device_t;
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_dircookie_t;
|
||||||
|
#define __WASI_DIRCOOKIE_START (0)
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_dirnamlen_t;
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_errno_t;
|
||||||
|
#define __WASI_ESUCCESS (0)
|
||||||
|
#define __WASI_E2BIG (1)
|
||||||
|
#define __WASI_EACCES (2)
|
||||||
|
#define __WASI_EADDRINUSE (3)
|
||||||
|
#define __WASI_EADDRNOTAVAIL (4)
|
||||||
|
#define __WASI_EAFNOSUPPORT (5)
|
||||||
|
#define __WASI_EAGAIN (6)
|
||||||
|
#define __WASI_EALREADY (7)
|
||||||
|
#define __WASI_EBADF (8)
|
||||||
|
#define __WASI_EBADMSG (9)
|
||||||
|
#define __WASI_EBUSY (10)
|
||||||
|
#define __WASI_ECANCELED (11)
|
||||||
|
#define __WASI_ECHILD (12)
|
||||||
|
#define __WASI_ECONNABORTED (13)
|
||||||
|
#define __WASI_ECONNREFUSED (14)
|
||||||
|
#define __WASI_ECONNRESET (15)
|
||||||
|
#define __WASI_EDEADLK (16)
|
||||||
|
#define __WASI_EDESTADDRREQ (17)
|
||||||
|
#define __WASI_EDOM (18)
|
||||||
|
#define __WASI_EDQUOT (19)
|
||||||
|
#define __WASI_EEXIST (20)
|
||||||
|
#define __WASI_EFAULT (21)
|
||||||
|
#define __WASI_EFBIG (22)
|
||||||
|
#define __WASI_EHOSTUNREACH (23)
|
||||||
|
#define __WASI_EIDRM (24)
|
||||||
|
#define __WASI_EILSEQ (25)
|
||||||
|
#define __WASI_EINPROGRESS (26)
|
||||||
|
#define __WASI_EINTR (27)
|
||||||
|
#define __WASI_EINVAL (28)
|
||||||
|
#define __WASI_EIO (29)
|
||||||
|
#define __WASI_EISCONN (30)
|
||||||
|
#define __WASI_EISDIR (31)
|
||||||
|
#define __WASI_ELOOP (32)
|
||||||
|
#define __WASI_EMFILE (33)
|
||||||
|
#define __WASI_EMLINK (34)
|
||||||
|
#define __WASI_EMSGSIZE (35)
|
||||||
|
#define __WASI_EMULTIHOP (36)
|
||||||
|
#define __WASI_ENAMETOOLONG (37)
|
||||||
|
#define __WASI_ENETDOWN (38)
|
||||||
|
#define __WASI_ENETRESET (39)
|
||||||
|
#define __WASI_ENETUNREACH (40)
|
||||||
|
#define __WASI_ENFILE (41)
|
||||||
|
#define __WASI_ENOBUFS (42)
|
||||||
|
#define __WASI_ENODEV (43)
|
||||||
|
#define __WASI_ENOENT (44)
|
||||||
|
#define __WASI_ENOEXEC (45)
|
||||||
|
#define __WASI_ENOLCK (46)
|
||||||
|
#define __WASI_ENOLINK (47)
|
||||||
|
#define __WASI_ENOMEM (48)
|
||||||
|
#define __WASI_ENOMSG (49)
|
||||||
|
#define __WASI_ENOPROTOOPT (50)
|
||||||
|
#define __WASI_ENOSPC (51)
|
||||||
|
#define __WASI_ENOSYS (52)
|
||||||
|
#define __WASI_ENOTCONN (53)
|
||||||
|
#define __WASI_ENOTDIR (54)
|
||||||
|
#define __WASI_ENOTEMPTY (55)
|
||||||
|
#define __WASI_ENOTRECOVERABLE (56)
|
||||||
|
#define __WASI_ENOTSOCK (57)
|
||||||
|
#define __WASI_ENOTSUP (58)
|
||||||
|
#define __WASI_ENOTTY (59)
|
||||||
|
#define __WASI_ENXIO (60)
|
||||||
|
#define __WASI_EOVERFLOW (61)
|
||||||
|
#define __WASI_EOWNERDEAD (62)
|
||||||
|
#define __WASI_EPERM (63)
|
||||||
|
#define __WASI_EPIPE (64)
|
||||||
|
#define __WASI_EPROTO (65)
|
||||||
|
#define __WASI_EPROTONOSUPPORT (66)
|
||||||
|
#define __WASI_EPROTOTYPE (67)
|
||||||
|
#define __WASI_ERANGE (68)
|
||||||
|
#define __WASI_EROFS (69)
|
||||||
|
#define __WASI_ESPIPE (70)
|
||||||
|
#define __WASI_ESRCH (71)
|
||||||
|
#define __WASI_ESTALE (72)
|
||||||
|
#define __WASI_ETIMEDOUT (73)
|
||||||
|
#define __WASI_ETXTBSY (74)
|
||||||
|
#define __WASI_EXDEV (75)
|
||||||
|
#define __WASI_ENOTCAPABLE (76)
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define ALIGNED_(x) __declspec(align(x))
|
||||||
|
#define WARN_UNUSED _Check_return_
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||||
|
#define WARN_UNUSED __attribute__((__warn_unused_result__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALIGNED_TYPE(t,x) typedef t ALIGNED_(x)
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_eventrwflags_t;
|
||||||
|
#define __WASI_EVENT_FD_READWRITE_HANGUP (0x0001)
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_eventtype_t;
|
||||||
|
#define __WASI_EVENTTYPE_CLOCK (0)
|
||||||
|
#define __WASI_EVENTTYPE_FD_READ (1)
|
||||||
|
#define __WASI_EVENTTYPE_FD_WRITE (2)
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_exitcode_t;
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_fd_t;
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_fdflags_t;
|
||||||
|
#define __WASI_FDFLAG_APPEND (0x0001)
|
||||||
|
#define __WASI_FDFLAG_DSYNC (0x0002)
|
||||||
|
#define __WASI_FDFLAG_NONBLOCK (0x0004)
|
||||||
|
#define __WASI_FDFLAG_RSYNC (0x0008)
|
||||||
|
#define __WASI_FDFLAG_SYNC (0x0010)
|
||||||
|
|
||||||
|
typedef int64_t __wasi_filedelta_t;
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_filesize_t;
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_filetype_t;
|
||||||
|
#define __WASI_FILETYPE_UNKNOWN (0)
|
||||||
|
#define __WASI_FILETYPE_BLOCK_DEVICE (1)
|
||||||
|
#define __WASI_FILETYPE_CHARACTER_DEVICE (2)
|
||||||
|
#define __WASI_FILETYPE_DIRECTORY (3)
|
||||||
|
#define __WASI_FILETYPE_REGULAR_FILE (4)
|
||||||
|
#define __WASI_FILETYPE_SOCKET_DGRAM (5)
|
||||||
|
#define __WASI_FILETYPE_SOCKET_STREAM (6)
|
||||||
|
#define __WASI_FILETYPE_SYMBOLIC_LINK (7)
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_fstflags_t;
|
||||||
|
#define __WASI_FILESTAT_SET_ATIM (0x0001)
|
||||||
|
#define __WASI_FILESTAT_SET_ATIM_NOW (0x0002)
|
||||||
|
#define __WASI_FILESTAT_SET_MTIM (0x0004)
|
||||||
|
#define __WASI_FILESTAT_SET_MTIM_NOW (0x0008)
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_inode_t;
|
||||||
|
|
||||||
|
ALIGNED_TYPE(uint64_t, 8) __wasi_linkcount_t;
|
||||||
|
|
||||||
|
typedef uint32_t __wasi_lookupflags_t;
|
||||||
|
#define __WASI_LOOKUP_SYMLINK_FOLLOW (0x00000001)
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_oflags_t;
|
||||||
|
#define __WASI_O_CREAT (0x0001)
|
||||||
|
#define __WASI_O_DIRECTORY (0x0002)
|
||||||
|
#define __WASI_O_EXCL (0x0004)
|
||||||
|
#define __WASI_O_TRUNC (0x0008)
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_riflags_t;
|
||||||
|
#define __WASI_SOCK_RECV_PEEK (0x0001)
|
||||||
|
#define __WASI_SOCK_RECV_WAITALL (0x0002)
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_rights_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observe that WASI defines rights in the plural form
|
||||||
|
* TODO: refactor to use RIGHTS instead of RIGHT
|
||||||
|
*/
|
||||||
|
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(UINT64_C(1) << 0))
|
||||||
|
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(UINT64_C(1) << 1))
|
||||||
|
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(UINT64_C(1) << 2))
|
||||||
|
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(UINT64_C(1) << 3))
|
||||||
|
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(UINT64_C(1) << 4))
|
||||||
|
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(UINT64_C(1) << 5))
|
||||||
|
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(UINT64_C(1) << 6))
|
||||||
|
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(UINT64_C(1) << 7))
|
||||||
|
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(UINT64_C(1) << 8))
|
||||||
|
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 9))
|
||||||
|
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(UINT64_C(1) << 10))
|
||||||
|
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 11))
|
||||||
|
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(UINT64_C(1) << 12))
|
||||||
|
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(UINT64_C(1) << 13))
|
||||||
|
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(UINT64_C(1) << 14))
|
||||||
|
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(UINT64_C(1) << 15))
|
||||||
|
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 16))
|
||||||
|
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(UINT64_C(1) << 17))
|
||||||
|
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 18))
|
||||||
|
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 19))
|
||||||
|
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 20))
|
||||||
|
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 21))
|
||||||
|
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 22))
|
||||||
|
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 23))
|
||||||
|
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(UINT64_C(1) << 24))
|
||||||
|
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 25))
|
||||||
|
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(UINT64_C(1) << 26))
|
||||||
|
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(UINT64_C(1) << 27))
|
||||||
|
#define __WASI_RIGHT_SOCK_CONNECT ((__wasi_rights_t)(UINT64_C(1) << 28))
|
||||||
|
#define __WASI_RIGHT_SOCK_LISTEN ((__wasi_rights_t)(UINT64_C(1) << 29))
|
||||||
|
#define __WASI_RIGHT_SOCK_BIND ((__wasi_rights_t)(UINT64_C(1) << 30))
|
||||||
|
#define __WASI_RIGHT_SOCK_ACCEPT ((__wasi_rights_t)(UINT64_C(1) << 31))
|
||||||
|
#define __WASI_RIGHT_SOCK_RECV ((__wasi_rights_t)(UINT64_C(1) << 32))
|
||||||
|
#define __WASI_RIGHT_SOCK_SEND ((__wasi_rights_t)(UINT64_C(1) << 33))
|
||||||
|
#define __WASI_RIGHT_SOCK_ADDR_LOCAL ((__wasi_rights_t)(UINT64_C(1) << 34))
|
||||||
|
#define __WASI_RIGHT_SOCK_ADDR_REMOTE ((__wasi_rights_t)(UINT64_C(1) << 35))
|
||||||
|
#define __WASI_RIGHT_SOCK_RECV_FROM ((__wasi_rights_t)(UINT64_C(1) << 36))
|
||||||
|
#define __WASI_RIGHT_SOCK_SEND_TO ((__wasi_rights_t)(UINT64_C(1) << 37))
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_roflags_t;
|
||||||
|
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_sdflags_t;
|
||||||
|
#define __WASI_SHUT_RD (0x01)
|
||||||
|
#define __WASI_SHUT_WR (0x02)
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_siflags_t;
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_signal_t;
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_subclockflags_t;
|
||||||
|
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_timestamp_t;
|
||||||
|
|
||||||
|
typedef uint64_t __wasi_userdata_t;
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_whence_t;
|
||||||
|
#define __WASI_WHENCE_SET (0)
|
||||||
|
#define __WASI_WHENCE_CUR (1)
|
||||||
|
#define __WASI_WHENCE_END (2)
|
||||||
|
|
||||||
|
typedef uint8_t __wasi_preopentype_t;
|
||||||
|
#define __WASI_PREOPENTYPE_DIR (0)
|
||||||
|
|
||||||
|
struct fd_table;
|
||||||
|
struct fd_prestats;
|
||||||
|
struct argv_environ_values;
|
||||||
|
struct addr_pool;
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(8) __wasi_dirent_t {
|
||||||
|
__wasi_dircookie_t d_next;
|
||||||
|
__wasi_inode_t d_ino;
|
||||||
|
__wasi_dirnamlen_t d_namlen;
|
||||||
|
__wasi_filetype_t d_type;
|
||||||
|
} __wasi_dirent_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_dirent_t, d_next) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_dirent_t, d_ino) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_dirent_t, d_namlen) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_dirent_t, d_type) == 20, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(__wasi_dirent_t) == 24, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_dirent_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(8) __wasi_event_t {
|
||||||
|
__wasi_userdata_t userdata;
|
||||||
|
__wasi_errno_t error;
|
||||||
|
__wasi_eventtype_t type;
|
||||||
|
uint8_t __paddings[5];
|
||||||
|
union __wasi_event_u {
|
||||||
|
struct __wasi_event_u_fd_readwrite_t {
|
||||||
|
__wasi_filesize_t nbytes;
|
||||||
|
__wasi_eventrwflags_t flags;
|
||||||
|
uint8_t __paddings[6];
|
||||||
|
} fd_readwrite;
|
||||||
|
} u;
|
||||||
|
} __wasi_event_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_event_t, userdata) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_event_t, error) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_event_t, type) == 10, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_event_t, u.fd_readwrite.nbytes) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_event_t, u.fd_readwrite.flags) == 24, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(__wasi_event_t) == 32, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_event_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct __wasi_prestat_t {
|
||||||
|
__wasi_preopentype_t pr_type;
|
||||||
|
union __wasi_prestat_u {
|
||||||
|
struct __wasi_prestat_u_dir_t {
|
||||||
|
size_t pr_name_len;
|
||||||
|
} dir;
|
||||||
|
} u;
|
||||||
|
} __wasi_prestat_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_prestat_t, pr_type) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
sizeof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
sizeof(__wasi_prestat_t) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
_Alignof(__wasi_prestat_t) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
_Alignof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(8) __wasi_fdstat_t {
|
||||||
|
__wasi_filetype_t fs_filetype;
|
||||||
|
__wasi_fdflags_t fs_flags;
|
||||||
|
uint8_t __paddings[4];
|
||||||
|
__wasi_rights_t fs_rights_base;
|
||||||
|
__wasi_rights_t fs_rights_inheriting;
|
||||||
|
} __wasi_fdstat_t;
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_fdstat_t, fs_filetype) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_fdstat_t, fs_flags) == 2, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_fdstat_t, fs_rights_base) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_fdstat_t, fs_rights_inheriting) == 16,
|
||||||
|
"non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(__wasi_fdstat_t) == 24, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_fdstat_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(8) __wasi_filestat_t {
|
||||||
|
__wasi_device_t st_dev;
|
||||||
|
__wasi_inode_t st_ino;
|
||||||
|
__wasi_filetype_t st_filetype;
|
||||||
|
__wasi_linkcount_t st_nlink;
|
||||||
|
__wasi_filesize_t st_size;
|
||||||
|
__wasi_timestamp_t st_atim;
|
||||||
|
__wasi_timestamp_t st_mtim;
|
||||||
|
__wasi_timestamp_t st_ctim;
|
||||||
|
} __wasi_filestat_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_filestat_t, st_dev) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_filestat_t, st_ino) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_filetype) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_nlink) == 24, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_size) == 32, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_atim) == 40, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_mtim) == 48, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(
|
||||||
|
offsetof(__wasi_filestat_t, st_ctim) == 56, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(__wasi_filestat_t) == 64, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_filestat_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct __wasi_ciovec_t {
|
||||||
|
const void *buf;
|
||||||
|
size_t buf_len;
|
||||||
|
} __wasi_ciovec_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_ciovec_t, buf) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
offsetof(__wasi_ciovec_t, buf_len) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
offsetof(__wasi_ciovec_t, buf_len) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
sizeof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
sizeof(__wasi_ciovec_t) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
_Alignof(__wasi_ciovec_t) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
_Alignof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
typedef struct __wasi_iovec_t {
|
||||||
|
void *buf;
|
||||||
|
size_t buf_len;
|
||||||
|
} __wasi_iovec_t;
|
||||||
|
assert_wasi_layout(offsetof(__wasi_iovec_t, buf) == 0, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
offsetof(__wasi_iovec_t, buf_len) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
offsetof(__wasi_iovec_t, buf_len) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
sizeof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
sizeof(__wasi_iovec_t) == 16, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||||
|
_Alignof(__wasi_iovec_t) == 4, "non-wasi data layout");
|
||||||
|
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||||
|
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of a `subscription` when type is `eventtype::clock`.
|
||||||
|
*/
|
||||||
|
typedef struct ALIGNED_(8) __wasi_subscription_clock_t {
|
||||||
|
/**
|
||||||
|
* The clock against which to compare the timestamp.
|
||||||
|
*/
|
||||||
|
__wasi_clockid_t clock_id;
|
||||||
|
|
||||||
|
uint8_t __paddings1[4];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute or relative timestamp.
|
||||||
|
*/
|
||||||
|
__wasi_timestamp_t timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of time that the implementation may wait additionally
|
||||||
|
* to coalesce with other events.
|
||||||
|
*/
|
||||||
|
__wasi_timestamp_t precision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags specifying whether the timeout is absolute or relative
|
||||||
|
*/
|
||||||
|
__wasi_subclockflags_t flags;
|
||||||
|
|
||||||
|
uint8_t __paddings2[4];
|
||||||
|
|
||||||
|
} __wasi_subscription_clock_t;
|
||||||
|
|
||||||
|
assert_wasi_layout(sizeof(__wasi_subscription_clock_t) == 32, "witx calculated size");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_subscription_clock_t) == 8, "witx calculated align");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, clock_id) == 0, "witx calculated offset");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, timeout) == 8, "witx calculated offset");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, precision) == 16, "witx calculated offset");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, flags) == 24, "witx calculated offset");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of a `subscription` when type is type is
|
||||||
|
* `eventtype::fd_read` or `eventtype::fd_write`.
|
||||||
|
*/
|
||||||
|
typedef struct __wasi_subscription_fd_readwrite_t {
|
||||||
|
/**
|
||||||
|
* The file descriptor on which to wait for it to become ready for reading or writing.
|
||||||
|
*/
|
||||||
|
__wasi_fd_t fd;
|
||||||
|
|
||||||
|
} __wasi_subscription_fd_readwrite_t;
|
||||||
|
|
||||||
|
assert_wasi_layout(sizeof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated size");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated align");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_fd_readwrite_t, fd) == 0, "witx calculated offset");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of a `subscription`.
|
||||||
|
*/
|
||||||
|
typedef union __wasi_subscription_u_u_t {
|
||||||
|
__wasi_subscription_clock_t clock;
|
||||||
|
__wasi_subscription_fd_readwrite_t fd_readwrite;
|
||||||
|
} __wasi_subscription_u_u_t ;
|
||||||
|
|
||||||
|
typedef struct ALIGNED_(8) __wasi_subscription_u_t {
|
||||||
|
__wasi_eventtype_t type;
|
||||||
|
__wasi_subscription_u_u_t u;
|
||||||
|
} __wasi_subscription_u_t;
|
||||||
|
|
||||||
|
assert_wasi_layout(sizeof(__wasi_subscription_u_t) == 40, "witx calculated size");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_subscription_u_t) == 8, "witx calculated align");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_u_t, u) == 8, "witx calculated union offset");
|
||||||
|
assert_wasi_layout(sizeof(__wasi_subscription_u_u_t) == 32, "witx calculated union size");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_subscription_u_u_t) == 8, "witx calculated union align");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription to an event.
|
||||||
|
*/
|
||||||
|
typedef struct __wasi_subscription_t {
|
||||||
|
/**
|
||||||
|
* User-provided value that is attached to the subscription in the
|
||||||
|
* implementation and returned through `event::userdata`.
|
||||||
|
*/
|
||||||
|
__wasi_userdata_t userdata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the event to which to subscribe, and its contents
|
||||||
|
*/
|
||||||
|
__wasi_subscription_u_t u;
|
||||||
|
|
||||||
|
} __wasi_subscription_t;
|
||||||
|
|
||||||
|
assert_wasi_layout(sizeof(__wasi_subscription_t) == 48, "witx calculated size");
|
||||||
|
assert_wasi_layout(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
|
||||||
|
assert_wasi_layout(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
|
||||||
|
|
||||||
|
/* keep syncing with wasi_socket_ext.h */
|
||||||
|
typedef enum {
|
||||||
|
/* Used only for sock_addr_resolve hints */
|
||||||
|
SOCKET_ANY = -1,
|
||||||
|
SOCKET_DGRAM = 0,
|
||||||
|
SOCKET_STREAM,
|
||||||
|
} __wasi_sock_type_t;
|
||||||
|
|
||||||
|
typedef uint16_t __wasi_ip_port_t;
|
||||||
|
|
||||||
|
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t;
|
||||||
|
|
||||||
|
/* n0.n1.n2.n3 */
|
||||||
|
typedef struct __wasi_addr_ip4_t {
|
||||||
|
uint8_t n0;
|
||||||
|
uint8_t n1;
|
||||||
|
uint8_t n2;
|
||||||
|
uint8_t n3;
|
||||||
|
} __wasi_addr_ip4_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_ip4_port_t {
|
||||||
|
__wasi_addr_ip4_t addr;
|
||||||
|
__wasi_ip_port_t port;
|
||||||
|
} __wasi_addr_ip4_port_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_ip6_t {
|
||||||
|
uint16_t n0;
|
||||||
|
uint16_t n1;
|
||||||
|
uint16_t n2;
|
||||||
|
uint16_t n3;
|
||||||
|
uint16_t h0;
|
||||||
|
uint16_t h1;
|
||||||
|
uint16_t h2;
|
||||||
|
uint16_t h3;
|
||||||
|
} __wasi_addr_ip6_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_ip6_port_t {
|
||||||
|
__wasi_addr_ip6_t addr;
|
||||||
|
__wasi_ip_port_t port;
|
||||||
|
} __wasi_addr_ip6_port_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_ip_t {
|
||||||
|
__wasi_addr_type_t kind;
|
||||||
|
union {
|
||||||
|
__wasi_addr_ip4_t ip4;
|
||||||
|
__wasi_addr_ip6_t ip6;
|
||||||
|
} addr;
|
||||||
|
} __wasi_addr_ip_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_t {
|
||||||
|
__wasi_addr_type_t kind;
|
||||||
|
union {
|
||||||
|
__wasi_addr_ip4_port_t ip4;
|
||||||
|
__wasi_addr_ip6_port_t ip6;
|
||||||
|
} addr;
|
||||||
|
} __wasi_addr_t;
|
||||||
|
|
||||||
|
typedef enum { INET4 = 0, INET6, INET_UNSPEC } __wasi_address_family_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_info_t {
|
||||||
|
__wasi_addr_t addr;
|
||||||
|
__wasi_sock_type_t type;
|
||||||
|
} __wasi_addr_info_t;
|
||||||
|
|
||||||
|
typedef struct __wasi_addr_info_hints_t {
|
||||||
|
__wasi_sock_type_t type;
|
||||||
|
__wasi_address_family_t family;
|
||||||
|
// this is to workaround lack of optional parameters
|
||||||
|
uint8_t hints_enabled;
|
||||||
|
} __wasi_addr_info_hints_t;
|
||||||
|
|
||||||
|
#undef assert_wasi_layout
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* end of _PLATFORM_WASI_TYPES_H */
|
|
@ -50,6 +50,7 @@ typedef pthread_t korp_thread;
|
||||||
typedef pthread_t korp_tid;
|
typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef unsigned int korp_sem;
|
typedef unsigned int korp_sem;
|
||||||
|
|
||||||
#ifndef SGX_DISABLE_PTHREAD
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
@ -68,6 +69,16 @@ strcpy(char *dest, const char *src);
|
||||||
#define os_memory_order_seq_cst __ATOMIC_SEQ_CST
|
#define os_memory_order_seq_cst __ATOMIC_SEQ_CST
|
||||||
#define os_atomic_thread_fence __atomic_thread_fence
|
#define os_atomic_thread_fence __atomic_thread_fence
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#define _LIBC_WASI_SGX_PFS_H
|
#define _LIBC_WASI_SGX_PFS_H
|
||||||
|
|
||||||
#include "bh_hashmap.h"
|
#include "bh_hashmap.h"
|
||||||
#include "wasmtime_ssp.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -120,13 +120,20 @@ strcpy(char *dest, const char *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
int mprot = 0;
|
int mprot = 0;
|
||||||
uint64 aligned_size, page_size;
|
uint64 aligned_size, page_size;
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
sgx_status_t st = 0;
|
sgx_status_t st = 0;
|
||||||
|
|
||||||
|
if (os_is_handle_valid(&file)) {
|
||||||
|
os_printf("os_mmap(size=%u, prot=0x%x, file=%x) failed: file is not "
|
||||||
|
"supported.\n",
|
||||||
|
size, prot, file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
page_size = getpagesize();
|
page_size = getpagesize();
|
||||||
aligned_size = (size + page_size - 1) & ~(page_size - 1);
|
aligned_size = (size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
|
@ -198,4 +205,4 @@ os_dcache_flush(void)
|
||||||
|
|
||||||
void
|
void
|
||||||
os_icache_flush(void *start, size_t len)
|
os_icache_flush(void *start, size_t len)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -213,4 +213,69 @@ os_thread_get_stack_boundary()
|
||||||
|
|
||||||
void
|
void
|
||||||
os_thread_jit_write_protect_np(bool enabled)
|
os_thread_jit_write_protect_np(bool enabled)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_init(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_init(lock, NULL) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_rdlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_rdlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_wrlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_wrlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_unlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_unlock(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_destroy(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
#ifndef SGX_DISABLE_PTHREAD
|
||||||
|
assert(lock);
|
||||||
|
|
||||||
|
if (pthread_rwlock_destroy(lock) != BHT_OK)
|
||||||
|
return BHT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -20,16 +20,23 @@ if (NOT BUILD_UNTRUST_PART EQUAL 1)
|
||||||
${SGX_SDK_DIR}/include/libcxx)
|
${SGX_SDK_DIR}/include/libcxx)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
|
||||||
add_definitions(-DSGX_DISABLE_WASI)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT WAMR_BUILD_THREAD_MGR EQUAL 1)
|
if (NOT WAMR_BUILD_THREAD_MGR EQUAL 1)
|
||||||
add_definitions(-DSGX_DISABLE_PTHREAD)
|
add_definitions(-DSGX_DISABLE_PTHREAD)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
file (GLOB source_all ${PLATFORM_SHARED_DIR}/*.c)
|
file (GLOB source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||||
|
|
||||||
|
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
add_definitions(-DSGX_DISABLE_WASI)
|
||||||
|
else()
|
||||||
|
list(APPEND source_all
|
||||||
|
${PLATFORM_SHARED_DIR}/../common/posix/posix_file.c
|
||||||
|
${PLATFORM_SHARED_DIR}/../common/posix/posix_clock.c
|
||||||
|
)
|
||||||
|
include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake)
|
||||||
|
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||||
|
endif()
|
||||||
|
|
||||||
file (GLOB source_all_untrusted ${PLATFORM_SHARED_DIR}/untrusted/*.c)
|
file (GLOB source_all_untrusted ${PLATFORM_SHARED_DIR}/untrusted/*.c)
|
||||||
|
|
||||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||||
|
|
|
@ -55,6 +55,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -121,6 +122,16 @@ os_sigreturn();
|
||||||
void
|
void
|
||||||
os_set_signal_number_for_blocking_op(int signo);
|
os_set_signal_number_for_blocking_op(int signo);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,7 +85,7 @@ os_dumps_proc_mem_info(char *out, unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||||
void *i_addr, *d_addr;
|
void *i_addr, *d_addr;
|
||||||
|
|
|
@ -41,6 +41,7 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
@ -129,6 +130,16 @@ fdopendir(int fd);
|
||||||
void
|
void
|
||||||
os_set_signal_number_for_blocking_op(int signo);
|
os_set_signal_number_for_blocking_op(int signo);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,5 +10,11 @@ include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||||
|
|
||||||
|
if (WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
list(APPEND source_all ${PLATFORM_SHARED_DIR}/../common/posix/posix_file.c)
|
||||||
|
include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake)
|
||||||
|
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||||
|
endif ()
|
||||||
|
|
||||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})
|
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,10 @@ typedef struct korp_cond {
|
||||||
#define os_printf printf
|
#define os_printf printf
|
||||||
#define os_vprintf vprintf
|
#define os_vprintf vprintf
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
#if WA_MATH
|
#if WA_MATH
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
/* math functions which are not provided by os*/
|
/* math functions which are not provided by os*/
|
||||||
|
@ -76,4 +80,10 @@ int isnan(double x);
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* end of _BH_PLATFORM_H */
|
#endif /* end of _BH_PLATFORM_H */
|
||||||
|
|
|
@ -50,7 +50,7 @@ os_dumps_proc_mem_info(char *out, unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
if (size > ((unsigned)~0))
|
if (size > ((unsigned)~0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -45,4 +45,14 @@ typedef rt_int16_t int16_t;
|
||||||
typedef rt_uint64_t uint64_t;
|
typedef rt_uint64_t uint64_t;
|
||||||
typedef rt_int64_t int64_t;
|
typedef rt_int64_t int64_t;
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* RTTHREAD_PLATFORM_INTERNAL_H */
|
#endif /* RTTHREAD_PLATFORM_INTERNAL_H */
|
||||||
|
|
|
@ -191,7 +191,7 @@ os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
return rt_malloc(size);
|
return rt_malloc(size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,12 +54,17 @@ typedef pthread_t korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef pthread_mutex_t korp_mutex;
|
||||||
typedef pthread_cond_t korp_cond;
|
typedef pthread_cond_t korp_cond;
|
||||||
typedef pthread_t korp_thread;
|
typedef pthread_t korp_thread;
|
||||||
|
typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef sem_t korp_sem;
|
typedef sem_t korp_sem;
|
||||||
|
|
||||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
|
||||||
#define os_thread_local_attribute __thread
|
#define os_thread_local_attribute __thread
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
||||||
|| defined(BUILD_TARGET_AARCH64)
|
|| defined(BUILD_TARGET_AARCH64)
|
||||||
|
@ -95,6 +100,12 @@ os_sigreturn();
|
||||||
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
|
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
|
||||||
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
|
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,10 +25,14 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#include <winapifamily.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <basetsd.h>
|
#include <basetsd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "platform_wasi_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -57,6 +61,11 @@ typedef void *korp_tid;
|
||||||
typedef void *korp_mutex;
|
typedef void *korp_mutex;
|
||||||
typedef void *korp_sem;
|
typedef void *korp_sem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SRWLOCK lock;
|
||||||
|
bool exclusive;
|
||||||
|
} korp_rwlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the mutex when os_mutex_lock is called, and no need to
|
* Create the mutex when os_mutex_lock is called, and no need to
|
||||||
* CloseHandle() for the static lock's lifetime, since
|
* CloseHandle() for the static lock's lifetime, since
|
||||||
|
@ -76,8 +85,6 @@ typedef struct korp_cond {
|
||||||
struct os_thread_wait_node *thread_wait_list_end;
|
struct os_thread_wait_node *thread_wait_list_end;
|
||||||
} korp_cond;
|
} korp_cond;
|
||||||
|
|
||||||
#define bh_socket_t SOCKET
|
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
os_getpagesize();
|
os_getpagesize();
|
||||||
void *
|
void *
|
||||||
|
@ -131,6 +138,61 @@ bh_atomic_thread_fence(int mem_order);
|
||||||
|
|
||||||
#define os_atomic_thread_fence bh_atomic_thread_fence
|
#define os_atomic_thread_fence bh_atomic_thread_fence
|
||||||
|
|
||||||
|
typedef enum windows_handle_type {
|
||||||
|
windows_handle_type_socket,
|
||||||
|
windows_handle_type_file
|
||||||
|
} windows_handle_type;
|
||||||
|
|
||||||
|
typedef enum windows_access_mode {
|
||||||
|
windows_access_mode_read = 1 << 0,
|
||||||
|
windows_access_mode_write = 1 << 1
|
||||||
|
} windows_access_mode;
|
||||||
|
|
||||||
|
typedef struct windows_handle {
|
||||||
|
windows_handle_type type;
|
||||||
|
__wasi_fdflags_t fdflags;
|
||||||
|
windows_access_mode access_mode;
|
||||||
|
union {
|
||||||
|
HANDLE handle;
|
||||||
|
SOCKET socket;
|
||||||
|
} raw;
|
||||||
|
} windows_handle;
|
||||||
|
|
||||||
|
typedef struct windows_dir_stream {
|
||||||
|
// Enough space for the wide filename and the info struct itself
|
||||||
|
char info_buf[PATH_MAX * sizeof(wchar_t) + sizeof(FILE_ID_BOTH_DIR_INFO)];
|
||||||
|
char current_entry_name[PATH_MAX];
|
||||||
|
// An offset into info_buf to read the next entry from
|
||||||
|
DWORD cursor;
|
||||||
|
int cookie;
|
||||||
|
windows_handle *handle;
|
||||||
|
} windows_dir_stream;
|
||||||
|
|
||||||
|
typedef windows_handle *os_file_handle;
|
||||||
|
typedef windows_dir_stream *os_dir_stream;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_UVWASI != 1
|
||||||
|
typedef HANDLE os_raw_file_handle;
|
||||||
|
#else
|
||||||
|
typedef uint32_t os_raw_file_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define bh_socket_t windows_handle *
|
||||||
|
|
||||||
|
// UWP apps do not have stdout/stderr handles so provide a default
|
||||||
|
// implementation of vprintf on debug builds so output from WASI libc is sent to
|
||||||
|
// the debugger and not lost completely.
|
||||||
|
#if !defined(BH_VPRINTF) && !defined(NDEBUG) && WINAPI_PARTITION_DESKTOP == 0
|
||||||
|
#define BH_VPRINTF uwp_print_to_debugger
|
||||||
|
#define UWP_DEFAULT_VPRINTF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,13 @@ include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c
|
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c
|
||||||
${PLATFORM_SHARED_DIR}/*.cpp)
|
${PLATFORM_SHARED_DIR}/*.cpp)
|
||||||
|
|
||||||
|
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/win_file.c)
|
||||||
|
else()
|
||||||
|
include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake)
|
||||||
|
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||||
|
endif()
|
||||||
|
|
||||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||||
|
|
||||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
||||||
|
|
|
@ -14,8 +14,8 @@ void
|
||||||
bh_atomic_thread_fence(int mem_order)
|
bh_atomic_thread_fence(int mem_order)
|
||||||
{
|
{
|
||||||
std::memory_order order =
|
std::memory_order order =
|
||||||
(std::memory_order)(std::memory_order::memory_order_relaxed + mem_order
|
(std::memory_order)((int)std::memory_order::memory_order_relaxed
|
||||||
- os_memory_order_relaxed);
|
+ mem_order - os_memory_order_relaxed);
|
||||||
std::atomic_thread_fence(order);
|
std::atomic_thread_fence(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
143
core/shared/platform/windows/win_clock.c
Normal file
143
core/shared/platform/windows/win_clock.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform_api_extension.h"
|
||||||
|
#include <winternl.h>
|
||||||
|
#include "win_util.h"
|
||||||
|
|
||||||
|
#define NANOSECONDS_PER_SECOND 1000000000ULL
|
||||||
|
#define NANOSECONDS_PER_TICK 100
|
||||||
|
|
||||||
|
static __wasi_errno_t
|
||||||
|
calculate_monotonic_clock_frequency(uint64 *out_frequency)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
if (!QueryPerformanceFrequency(&frequency))
|
||||||
|
return convert_windows_error_code(GetLastError());
|
||||||
|
|
||||||
|
*out_frequency = (uint64)frequency.QuadPart;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __wasi_errno_t
|
||||||
|
get_performance_counter_value(uint64 *out_counter)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER counter;
|
||||||
|
if (!QueryPerformanceCounter(&counter))
|
||||||
|
return convert_windows_error_code(GetLastError());
|
||||||
|
|
||||||
|
*out_counter = counter.QuadPart;
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
|
||||||
|
{
|
||||||
|
__wasi_errno_t error = __WASI_ESUCCESS;
|
||||||
|
|
||||||
|
switch (clock_id) {
|
||||||
|
case __WASI_CLOCK_MONOTONIC:
|
||||||
|
{
|
||||||
|
uint64 frequency;
|
||||||
|
error = calculate_monotonic_clock_frequency(&frequency);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
const uint64 result = (uint64)NANOSECONDS_PER_SECOND / frequency;
|
||||||
|
*resolution = result;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
case __WASI_CLOCK_REALTIME:
|
||||||
|
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||||
|
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||||
|
{
|
||||||
|
#if WINAPI_PARTITION_DESKTOP
|
||||||
|
ULONG maximum_time;
|
||||||
|
ULONG minimum_time;
|
||||||
|
ULONG current_time;
|
||||||
|
NTSTATUS
|
||||||
|
status = NtQueryTimerResolution(&maximum_time, &minimum_time,
|
||||||
|
¤t_time);
|
||||||
|
uint64 result = (uint64)current_time * NANOSECONDS_PER_TICK;
|
||||||
|
*resolution = result / (uint64)NANOSECONDS_PER_SECOND;
|
||||||
|
return error;
|
||||||
|
#else
|
||||||
|
return __WASI_ENOTSUP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||||
|
__wasi_timestamp_t *time)
|
||||||
|
{
|
||||||
|
__wasi_errno_t error = __WASI_ESUCCESS;
|
||||||
|
|
||||||
|
switch (clock_id) {
|
||||||
|
case __WASI_CLOCK_REALTIME:
|
||||||
|
{
|
||||||
|
FILETIME sys_now;
|
||||||
|
#if NTDDI_VERSION >= NTDDI_WIN8
|
||||||
|
GetSystemTimePreciseAsFileTime(&sys_now);
|
||||||
|
#else
|
||||||
|
GetSystemTimeAsFileTime(&sys_now);
|
||||||
|
#endif
|
||||||
|
*time = convert_filetime_to_wasi_timestamp(&sys_now);
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
case __WASI_CLOCK_MONOTONIC:
|
||||||
|
{
|
||||||
|
uint64 frequency;
|
||||||
|
error = calculate_monotonic_clock_frequency(&frequency);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
uint64 counter;
|
||||||
|
error = get_performance_counter_value(&counter);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (NANOSECONDS_PER_SECOND % frequency == 0) {
|
||||||
|
*time = counter * NANOSECONDS_PER_SECOND / frequency;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint64 seconds = counter / frequency;
|
||||||
|
uint64 fractions = counter % frequency;
|
||||||
|
*time = seconds * NANOSECONDS_PER_SECOND
|
||||||
|
+ (fractions * NANOSECONDS_PER_SECOND) / frequency;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||||
|
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||||
|
{
|
||||||
|
FILETIME creation_time;
|
||||||
|
FILETIME exit_time;
|
||||||
|
FILETIME kernel_time;
|
||||||
|
FILETIME user_time;
|
||||||
|
|
||||||
|
HANDLE handle = (clock_id == __WASI_CLOCK_PROCESS_CPUTIME_ID)
|
||||||
|
? GetCurrentProcess()
|
||||||
|
: GetCurrentThread();
|
||||||
|
|
||||||
|
if (!GetProcessTimes(handle, &creation_time, &exit_time,
|
||||||
|
&kernel_time, &user_time))
|
||||||
|
return convert_windows_error_code(GetLastError());
|
||||||
|
|
||||||
|
*time = convert_filetime_to_wasi_timestamp(&kernel_time)
|
||||||
|
+ convert_filetime_to_wasi_timestamp(&user_time);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
1491
core/shared/platform/windows/win_file.c
Normal file
1491
core/shared/platform/windows/win_file.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -29,7 +29,7 @@ access_to_win32_flags(int prot)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
DWORD alloc_type = MEM_RESERVE;
|
DWORD alloc_type = MEM_RESERVE;
|
||||||
DWORD protect;
|
DWORD protect;
|
||||||
|
|
|
@ -11,6 +11,22 @@
|
||||||
|
|
||||||
static bool is_winsock_inited = false;
|
static bool is_winsock_inited = false;
|
||||||
|
|
||||||
|
#define CHECK_VALID_SOCKET_HANDLE(win_handle) \
|
||||||
|
do { \
|
||||||
|
if ((win_handle) == NULL) { \
|
||||||
|
errno = EBADF; \
|
||||||
|
return BHT_ERROR; \
|
||||||
|
} \
|
||||||
|
if ((win_handle)->type != windows_handle_type_socket) { \
|
||||||
|
errno = ENOTSOCK; \
|
||||||
|
return BHT_ERROR; \
|
||||||
|
} \
|
||||||
|
if ((win_handle)->raw.socket == INVALID_SOCKET) { \
|
||||||
|
errno = EBADF; \
|
||||||
|
return BHT_ERROR; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
int
|
int
|
||||||
init_winsock()
|
init_winsock()
|
||||||
{
|
{
|
||||||
|
@ -45,6 +61,17 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*(sock) = BH_MALLOC(sizeof(windows_handle));
|
||||||
|
|
||||||
|
if ((*sock) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return BHT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*sock)->type = windows_handle_type_socket;
|
||||||
|
(*sock)->access_mode = windows_access_mode_read | windows_access_mode_write;
|
||||||
|
(*sock)->fdflags = 0;
|
||||||
|
|
||||||
if (is_ipv4) {
|
if (is_ipv4) {
|
||||||
af = AF_INET;
|
af = AF_INET;
|
||||||
}
|
}
|
||||||
|
@ -54,18 +81,24 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_tcp) {
|
if (is_tcp) {
|
||||||
*sock = socket(af, SOCK_STREAM, IPPROTO_TCP);
|
(*sock)->raw.socket = socket(af, SOCK_STREAM, IPPROTO_TCP);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*sock = socket(af, SOCK_DGRAM, 0);
|
(*sock)->raw.socket = socket(af, SOCK_DGRAM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*sock == -1) ? BHT_ERROR : BHT_OK;
|
if ((*sock)->raw.socket == INVALID_SOCKET) {
|
||||||
|
BH_FREE(*sock);
|
||||||
|
return BHT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int socklen, ret;
|
int socklen, ret;
|
||||||
|
|
||||||
|
@ -76,13 +109,13 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||||
addr.sin_port = htons(*port);
|
addr.sin_port = htons(*port);
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
|
|
||||||
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
|
ret = bind(socket->raw.socket, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
socklen = sizeof(addr);
|
socklen = sizeof(addr);
|
||||||
if (getsockname(socket, (void *)&addr, &socklen) == -1) {
|
if (getsockname(socket->raw.socket, (void *)&addr, &socklen) == -1) {
|
||||||
os_printf("getsockname failed with error %d\n", WSAGetLastError());
|
os_printf("getsockname failed with error %d\n", WSAGetLastError());
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -98,10 +131,12 @@ fail:
|
||||||
int
|
int
|
||||||
os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
|
os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
DWORD tv = (DWORD)(timeout_us / 1000UL);
|
DWORD tv = (DWORD)(timeout_us / 1000UL);
|
||||||
|
|
||||||
if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv,
|
if (setsockopt(socket->raw.socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||||
sizeof(tv))
|
(const char *)&tv, sizeof(tv))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +147,9 @@ os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
int
|
int
|
||||||
os_socket_listen(bh_socket_t socket, int max_client)
|
os_socket_listen(bh_socket_t socket, int max_client)
|
||||||
{
|
{
|
||||||
if (listen(socket, max_client) != 0) {
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
if (listen(socket->raw.socket, max_client) != 0) {
|
||||||
os_printf("socket listen failed with error %d\n", WSAGetLastError());
|
os_printf("socket listen failed with error %d\n", WSAGetLastError());
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -124,12 +161,26 @@ int
|
||||||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||||
unsigned int *addrlen)
|
unsigned int *addrlen)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(server_sock);
|
||||||
|
|
||||||
struct sockaddr addr_tmp;
|
struct sockaddr addr_tmp;
|
||||||
unsigned int len = sizeof(struct sockaddr);
|
unsigned int len = sizeof(struct sockaddr);
|
||||||
|
|
||||||
*sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len);
|
*sock = BH_MALLOC(sizeof(windows_handle));
|
||||||
|
|
||||||
if (*sock < 0) {
|
if (*sock == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return BHT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*sock)->type = windows_handle_type_socket;
|
||||||
|
(*sock)->access_mode = windows_access_mode_read | windows_access_mode_write;
|
||||||
|
(*sock)->fdflags = 0;
|
||||||
|
(*sock)->raw.socket =
|
||||||
|
accept(server_sock->raw.socket, (struct sockaddr *)&addr_tmp, &len);
|
||||||
|
|
||||||
|
if ((*sock)->raw.socket == INVALID_SOCKET) {
|
||||||
|
BH_FREE(*sock);
|
||||||
os_printf("socket accept failed with error %d\n", WSAGetLastError());
|
os_printf("socket accept failed with error %d\n", WSAGetLastError());
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -140,13 +191,17 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||||
int
|
int
|
||||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return recv(socket, buf, len, 0);
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
return recv(socket->raw.socket, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
||||||
bh_sockaddr_t *src_addr)
|
bh_sockaddr_t *src_addr)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -155,13 +210,17 @@ os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
||||||
int
|
int
|
||||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return send(socket, buf, len, 0);
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
return send(socket->raw.socket, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
||||||
int flags, const bh_sockaddr_t *dest_addr)
|
int flags, const bh_sockaddr_t *dest_addr)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -170,14 +229,21 @@ os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
||||||
int
|
int
|
||||||
os_socket_close(bh_socket_t socket)
|
os_socket_close(bh_socket_t socket)
|
||||||
{
|
{
|
||||||
closesocket(socket);
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
closesocket(socket->raw.socket);
|
||||||
|
|
||||||
|
BH_FREE(socket);
|
||||||
|
|
||||||
return BHT_OK;
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_socket_shutdown(bh_socket_t socket)
|
os_socket_shutdown(bh_socket_t socket)
|
||||||
{
|
{
|
||||||
shutdown(socket, SD_BOTH);
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
shutdown(socket->raw.socket, SD_BOTH);
|
||||||
return BHT_OK;
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +272,16 @@ os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
|
||||||
return BHT_OK;
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_socket_connect(bh_socket_t socket, const char *addr, int port)
|
||||||
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
|
errno = ENOSYS;
|
||||||
|
|
||||||
|
return BHT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_socket_addr_resolve(const char *host, const char *service,
|
os_socket_addr_resolve(const char *host, const char *service,
|
||||||
uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
|
uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
|
||||||
|
@ -220,6 +296,8 @@ os_socket_addr_resolve(const char *host, const char *service,
|
||||||
int
|
int
|
||||||
os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -228,6 +306,8 @@ os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
||||||
int
|
int
|
||||||
os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
|
os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -236,6 +316,8 @@ os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
int
|
int
|
||||||
os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
|
os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -244,6 +326,8 @@ os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
|
||||||
int
|
int
|
||||||
os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
|
os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -252,6 +336,8 @@ os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
|
||||||
int
|
int
|
||||||
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
|
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -260,6 +346,8 @@ os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
|
||||||
int
|
int
|
||||||
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -268,6 +356,8 @@ os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
|
||||||
int
|
int
|
||||||
os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
|
os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -276,6 +366,8 @@ os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
|
||||||
int
|
int
|
||||||
os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
|
os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -284,6 +376,8 @@ os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
|
||||||
int
|
int
|
||||||
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
|
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -292,6 +386,8 @@ os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
|
||||||
int
|
int
|
||||||
os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
|
os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -300,6 +396,8 @@ os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
|
||||||
int
|
int
|
||||||
os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
|
os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -308,6 +406,8 @@ os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -316,6 +416,8 @@ os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
|
os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -324,6 +426,8 @@ os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -332,6 +436,8 @@ os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
|
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -340,6 +446,8 @@ os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -348,6 +456,8 @@ os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
|
os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -356,6 +466,8 @@ os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
|
||||||
int
|
int
|
||||||
os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
|
os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -364,6 +476,8 @@ os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
|
||||||
int
|
int
|
||||||
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
|
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -372,6 +486,8 @@ os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -380,6 +496,8 @@ os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
|
os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -388,6 +506,8 @@ os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -396,6 +516,8 @@ os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
|
os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -404,6 +526,8 @@ os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
|
||||||
int
|
int
|
||||||
os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
|
os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -412,6 +536,8 @@ os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
|
||||||
int
|
int
|
||||||
os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
|
os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -420,6 +546,8 @@ os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
|
||||||
int
|
int
|
||||||
os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
|
os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -428,6 +556,8 @@ os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
|
||||||
int
|
int
|
||||||
os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
|
os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -436,6 +566,8 @@ os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -444,6 +576,8 @@ os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
|
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -452,6 +586,8 @@ os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
|
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -462,6 +598,8 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
|
||||||
bh_ip_addr_buffer_t *imr_multiaddr,
|
bh_ip_addr_buffer_t *imr_multiaddr,
|
||||||
uint32_t imr_interface, bool is_ipv6)
|
uint32_t imr_interface, bool is_ipv6)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -472,6 +610,8 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
|
||||||
bh_ip_addr_buffer_t *imr_multiaddr,
|
bh_ip_addr_buffer_t *imr_multiaddr,
|
||||||
uint32_t imr_interface, bool is_ipv6)
|
uint32_t imr_interface, bool is_ipv6)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -480,6 +620,8 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
|
||||||
int
|
int
|
||||||
os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
|
os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -488,6 +630,8 @@ os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
|
||||||
int
|
int
|
||||||
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -496,6 +640,8 @@ os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
||||||
int
|
int
|
||||||
os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
|
os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -504,6 +650,8 @@ os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
|
||||||
int
|
int
|
||||||
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -512,6 +660,8 @@ os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
|
||||||
int
|
int
|
||||||
os_socket_set_ipv6_only(bh_socket_t socket, bool option)
|
os_socket_set_ipv6_only(bh_socket_t socket, bool option)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -520,6 +670,8 @@ os_socket_set_ipv6_only(bh_socket_t socket, bool option)
|
||||||
int
|
int
|
||||||
os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
|
os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -528,6 +680,8 @@ os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
|
||||||
int
|
int
|
||||||
os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
|
os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
@ -536,6 +690,8 @@ os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
|
||||||
int
|
int
|
||||||
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
|
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
|
||||||
{
|
{
|
||||||
|
CHECK_VALID_SOCKET_HANDLE(socket);
|
||||||
|
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,6 +541,62 @@ os_mutex_unlock(korp_mutex *mutex)
|
||||||
return ReleaseMutex(*mutex) ? BHT_OK : BHT_ERROR;
|
return ReleaseMutex(*mutex) ? BHT_OK : BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_init(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
bh_assert(lock);
|
||||||
|
|
||||||
|
InitializeSRWLock(&(lock->lock));
|
||||||
|
lock->exclusive = false;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_rdlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
bh_assert(lock);
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&(lock->lock));
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_wrlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
bh_assert(lock);
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&(lock->lock));
|
||||||
|
lock->exclusive = true;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_unlock(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
bh_assert(lock);
|
||||||
|
|
||||||
|
if (lock->exclusive) {
|
||||||
|
lock->exclusive = false;
|
||||||
|
ReleaseSRWLockExclusive(&(lock->lock));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReleaseSRWLockShared(&(lock->lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
os_rwlock_destroy(korp_rwlock *lock)
|
||||||
|
{
|
||||||
|
(void)lock;
|
||||||
|
|
||||||
|
return BHT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_cond_init(korp_cond *cond)
|
os_cond_init(korp_cond *cond)
|
||||||
{
|
{
|
||||||
|
|
96
core/shared/platform/windows/win_util.c
Normal file
96
core/shared/platform/windows/win_util.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform_common.h"
|
||||||
|
#include "win_util.h"
|
||||||
|
|
||||||
|
__wasi_timestamp_t
|
||||||
|
convert_filetime_to_wasi_timestamp(LPFILETIME filetime)
|
||||||
|
{
|
||||||
|
// From 1601-01-01 to 1970-01-01 there are 134774 days.
|
||||||
|
static const uint64_t NT_to_UNIX_epoch =
|
||||||
|
134774ull * 86400ull * 1000ull * 1000ull * 1000ull;
|
||||||
|
|
||||||
|
ULARGE_INTEGER temp = { .HighPart = filetime->dwHighDateTime,
|
||||||
|
.LowPart = filetime->dwLowDateTime };
|
||||||
|
|
||||||
|
// WASI timestamps are measured in nanoseconds whereas FILETIME structs are
|
||||||
|
// represented in terms 100-nanosecond intervals.
|
||||||
|
return (temp.QuadPart * 100ull) - NT_to_UNIX_epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_windows_error_code(DWORD windows_error_code)
|
||||||
|
{
|
||||||
|
switch (windows_error_code) {
|
||||||
|
case ERROR_INVALID_PARAMETER:
|
||||||
|
case ERROR_INVALID_HANDLE:
|
||||||
|
case ERROR_NEGATIVE_SEEK:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_PIPE_BUSY:
|
||||||
|
return __WASI_EBUSY;
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
return __WASI_EACCES;
|
||||||
|
case ERROR_ALREADY_EXISTS:
|
||||||
|
case ERROR_FILE_EXISTS:
|
||||||
|
return __WASI_EEXIST;
|
||||||
|
case ERROR_NO_MORE_FILES:
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
case ERROR_INVALID_NAME:
|
||||||
|
return __WASI_ENOENT;
|
||||||
|
case ERROR_PRIVILEGE_NOT_HELD:
|
||||||
|
return __WASI_EPERM;
|
||||||
|
case ERROR_NOT_ENOUGH_MEMORY:
|
||||||
|
return __WASI_ENOMEM;
|
||||||
|
case ERROR_NOACCESS:
|
||||||
|
return __WASI_EFAULT;
|
||||||
|
case ERROR_DIR_NOT_EMPTY:
|
||||||
|
return __WASI_ENOTEMPTY;
|
||||||
|
case ERROR_DIRECTORY:
|
||||||
|
return __WASI_ENOTDIR;
|
||||||
|
case ERROR_IO_PENDING:
|
||||||
|
case ERROR_INSUFFICIENT_BUFFER:
|
||||||
|
case ERROR_INVALID_FLAGS:
|
||||||
|
case ERROR_NO_UNICODE_TRANSLATION:
|
||||||
|
default:
|
||||||
|
return __WASI_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UWP_DEFAULT_VPRINTF
|
||||||
|
int
|
||||||
|
uwp_print_to_debugger(const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
// Provide a stack buffer which should be large enough for any realistic
|
||||||
|
// string so we avoid making an allocation on every printf call.
|
||||||
|
char stack_buf[2048];
|
||||||
|
char *buf = stack_buf;
|
||||||
|
int ret = vsnprintf(stack_buf, sizeof(stack_buf), format, ap);
|
||||||
|
|
||||||
|
if ((size_t)ret >= sizeof(stack_buf)) {
|
||||||
|
// Allocate an extra byte for the null terminator.
|
||||||
|
char *heap_buf = BH_MALLOC((unsigned int)(ret) + 1);
|
||||||
|
buf = heap_buf;
|
||||||
|
|
||||||
|
if (heap_buf == NULL) {
|
||||||
|
// Output as much as we can to the debugger if allocating a buffer
|
||||||
|
// fails.
|
||||||
|
OutputDebugStringA(stack_buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = vsnprintf(heap_buf, (size_t)ret + 1, format, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
OutputDebugStringA(buf);
|
||||||
|
|
||||||
|
if (buf != stack_buf)
|
||||||
|
BH_FREE(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
19
core/shared/platform/windows/win_util.h
Normal file
19
core/shared/platform/windows/win_util.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WIN_UTIL_H
|
||||||
|
#define _WIN_UTIL_H
|
||||||
|
|
||||||
|
#include "platform_wasi_types.h"
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
__wasi_timestamp_t
|
||||||
|
convert_filetime_to_wasi_timestamp(LPFILETIME filetime);
|
||||||
|
|
||||||
|
// Convert a Windows error code to a WASI error code
|
||||||
|
__wasi_errno_t
|
||||||
|
convert_windows_error_code(DWORD windows_error_code);
|
||||||
|
|
||||||
|
#endif /* end of _WIN_UTIL_H */
|
|
@ -42,21 +42,23 @@
|
||||||
#include <net/net_ip.h>
|
#include <net/net_ip.h>
|
||||||
#include <net/net_core.h>
|
#include <net/net_core.h>
|
||||||
#include <net/net_context.h>
|
#include <net/net_context.h>
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_MPU
|
|
||||||
#include <arch/arm/aarch32/cortex_m/cmsis.h>
|
|
||||||
#endif
|
|
||||||
#else /* else of KERNEL_VERSION_NUMBER < 0x030200 */
|
#else /* else of KERNEL_VERSION_NUMBER < 0x030200 */
|
||||||
#include <zephyr/net/net_pkt.h>
|
#include <zephyr/net/net_pkt.h>
|
||||||
#include <zephyr/net/net_if.h>
|
#include <zephyr/net/net_if.h>
|
||||||
#include <zephyr/net/net_ip.h>
|
#include <zephyr/net/net_ip.h>
|
||||||
#include <zephyr/net/net_core.h>
|
#include <zephyr/net/net_core.h>
|
||||||
#include <zephyr/net/net_context.h>
|
#include <zephyr/net/net_context.h>
|
||||||
|
#endif /* end of KERNEL_VERSION_NUMBER < 0x030200 */
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_MPU
|
#ifdef CONFIG_ARM_MPU
|
||||||
|
#if KERNEL_VERSION_NUMBER < 0x030200 /* version 3.2.0 */
|
||||||
|
#include <arch/arm/aarch32/cortex_m/cmsis.h>
|
||||||
|
#elif KERNEL_VERSION_NUMBER < 0x030400 /* version 3.4.0 */
|
||||||
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
|
||||||
|
#else /* > 3.4.0 */
|
||||||
|
#include <cmsis_core.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif /* end of KERNEL_VERSION_NUMBER < 0x030200 */
|
|
||||||
|
|
||||||
#ifndef BH_PLATFORM_ZEPHYR
|
#ifndef BH_PLATFORM_ZEPHYR
|
||||||
#define BH_PLATFORM_ZEPHYR
|
#define BH_PLATFORM_ZEPHYR
|
||||||
|
@ -146,4 +148,14 @@ void
|
||||||
set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func,
|
set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func,
|
||||||
exec_mem_free_func_t free_func);
|
exec_mem_free_func_t free_func);
|
||||||
|
|
||||||
|
typedef int os_file_handle;
|
||||||
|
typedef DIR *os_dir_stream;
|
||||||
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
|
static inline os_file_handle
|
||||||
|
os_get_invalid_handle()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -173,7 +173,7 @@ strcspn(const char *s, const char *reject)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *
|
void *
|
||||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
||||||
{
|
{
|
||||||
if ((uint64)size >= UINT32_MAX)
|
if ((uint64)size >= UINT32_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -155,7 +155,7 @@ As function parameters are always passed in 32 bits numbers, you can also use 'i
|
||||||
//
|
//
|
||||||
// If the function signature used i32 data type ("i")
|
// If the function signature used i32 data type ("i")
|
||||||
// for buffer address or string parameters, here
|
// for buffer address or string parameters, here
|
||||||
// is how to do address conversation and boundary check manually
|
// is how to do address conversion and boundary check manually
|
||||||
//
|
//
|
||||||
void foo2(wasm_exec_env_t exec_env,
|
void foo2(wasm_exec_env_t exec_env,
|
||||||
uint32 msg_offset,
|
uint32 msg_offset,
|
||||||
|
|
174
product-mini/platforms/common/libc_wasi.c
Normal file
174
product-mini/platforms/common/libc_wasi.c
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "bh_platform.h"
|
||||||
|
#include "wasm_export.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *dir_list[8];
|
||||||
|
uint32 dir_list_size;
|
||||||
|
const char *map_dir_list[8];
|
||||||
|
uint32 map_dir_list_size;
|
||||||
|
const char *env_list[8];
|
||||||
|
uint32 env_list_size;
|
||||||
|
const char *addr_pool[8];
|
||||||
|
uint32 addr_pool_size;
|
||||||
|
const char *ns_lookup_pool[8];
|
||||||
|
uint32 ns_lookup_pool_size;
|
||||||
|
} libc_wasi_parse_context_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LIBC_WASI_PARSE_RESULT_OK = 0,
|
||||||
|
LIBC_WASI_PARSE_RESULT_NEED_HELP,
|
||||||
|
LIBC_WASI_PARSE_RESULT_BAD_PARAM
|
||||||
|
} libc_wasi_parse_result_t;
|
||||||
|
|
||||||
|
static void
|
||||||
|
libc_wasi_print_help()
|
||||||
|
{
|
||||||
|
printf(" --env=<env> Pass wasi environment variables with "
|
||||||
|
"\"key=value\"\n");
|
||||||
|
printf(" to the program, for example:\n");
|
||||||
|
printf(" --env=\"key1=value1\" "
|
||||||
|
"--env=\"key2=value2\"\n");
|
||||||
|
printf(" --dir=<dir> Grant wasi access to the given host "
|
||||||
|
"directories\n");
|
||||||
|
printf(" to the program, for example:\n");
|
||||||
|
printf(" --dir=<dir1> --dir=<dir2>\n");
|
||||||
|
printf(" --map-dir=<guest::host> Grant wasi access to the given host "
|
||||||
|
"directories\n");
|
||||||
|
printf(" to the program at a specific guest "
|
||||||
|
"path, for example:\n");
|
||||||
|
printf(" --map-dir=<guest-path1::host-path1> "
|
||||||
|
"--map-dir=<guest-path2::host-path2>\n");
|
||||||
|
printf(" --addr-pool=<addrs> Grant wasi access to the given network "
|
||||||
|
"addresses in\n");
|
||||||
|
printf(" CIRD notation to the program, seperated "
|
||||||
|
"with ',',\n");
|
||||||
|
printf(" for example:\n");
|
||||||
|
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
|
||||||
|
printf(" --allow-resolve=<domain> Allow the lookup of the specific domain "
|
||||||
|
"name or domain\n");
|
||||||
|
printf(" name suffixes using a wildcard, for "
|
||||||
|
"example:\n");
|
||||||
|
printf(" --allow-resolve=example.com # allow the "
|
||||||
|
"lookup of the specific domain\n");
|
||||||
|
printf(" --allow-resolve=*.example.com # allow "
|
||||||
|
"the lookup of all subdomains\n");
|
||||||
|
printf(" --allow-resolve=* # allow any lookup\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
validate_env_str(char *env)
|
||||||
|
{
|
||||||
|
char *p = env;
|
||||||
|
int key_len = 0;
|
||||||
|
|
||||||
|
while (*p != '\0' && *p != '=') {
|
||||||
|
key_len++;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p != '=' || key_len == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
libc_wasi_parse_result_t
|
||||||
|
libc_wasi_parse(char *arg, libc_wasi_parse_context_t *ctx)
|
||||||
|
{
|
||||||
|
if (!strncmp(arg, "--dir=", 6)) {
|
||||||
|
if (arg[6] == '\0')
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
if (ctx->dir_list_size >= sizeof(ctx->dir_list) / sizeof(char *)) {
|
||||||
|
printf("Only allow max dir number %d\n",
|
||||||
|
(int)(sizeof(ctx->dir_list) / sizeof(char *)));
|
||||||
|
return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
|
||||||
|
}
|
||||||
|
ctx->dir_list[ctx->dir_list_size++] = arg + 6;
|
||||||
|
}
|
||||||
|
else if (!strncmp(arg, "--map-dir=", 10)) {
|
||||||
|
if (arg[10] == '\0')
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
if (ctx->map_dir_list_size
|
||||||
|
>= sizeof(ctx->map_dir_list) / sizeof(char *)) {
|
||||||
|
printf("Only allow max map dir number %d\n",
|
||||||
|
(int)(sizeof(ctx->map_dir_list) / sizeof(char *)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ctx->map_dir_list[ctx->map_dir_list_size++] = arg + 10;
|
||||||
|
}
|
||||||
|
else if (!strncmp(arg, "--env=", 6)) {
|
||||||
|
char *tmp_env;
|
||||||
|
|
||||||
|
if (arg[6] == '\0')
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
if (ctx->env_list_size >= sizeof(ctx->env_list) / sizeof(char *)) {
|
||||||
|
printf("Only allow max env number %d\n",
|
||||||
|
(int)(sizeof(ctx->env_list) / sizeof(char *)));
|
||||||
|
return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
|
||||||
|
}
|
||||||
|
tmp_env = arg + 6;
|
||||||
|
if (validate_env_str(tmp_env))
|
||||||
|
ctx->env_list[ctx->env_list_size++] = tmp_env;
|
||||||
|
else {
|
||||||
|
printf("Wasm parse env string failed: expect \"key=value\", "
|
||||||
|
"got \"%s\"\n",
|
||||||
|
tmp_env);
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO: parse the configuration file via --addr-pool-file */
|
||||||
|
else if (!strncmp(arg, "--addr-pool=", strlen("--addr-pool="))) {
|
||||||
|
/* like: --addr-pool=100.200.244.255/30 */
|
||||||
|
char *token = NULL;
|
||||||
|
|
||||||
|
if ('\0' == arg[12])
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
|
||||||
|
token = strtok(arg + strlen("--addr-pool="), ",");
|
||||||
|
while (token) {
|
||||||
|
if (ctx->addr_pool_size
|
||||||
|
>= sizeof(ctx->addr_pool) / sizeof(char *)) {
|
||||||
|
printf("Only allow max address number %d\n",
|
||||||
|
(int)(sizeof(ctx->addr_pool) / sizeof(char *)));
|
||||||
|
return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->addr_pool[ctx->addr_pool_size++] = token;
|
||||||
|
token = strtok(NULL, ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strncmp(arg, "--allow-resolve=", 16)) {
|
||||||
|
if (arg[16] == '\0')
|
||||||
|
return LIBC_WASI_PARSE_RESULT_NEED_HELP;
|
||||||
|
if (ctx->ns_lookup_pool_size
|
||||||
|
>= sizeof(ctx->ns_lookup_pool) / sizeof(ctx->ns_lookup_pool[0])) {
|
||||||
|
printf("Only allow max ns lookup number %d\n",
|
||||||
|
(int)(sizeof(ctx->ns_lookup_pool)
|
||||||
|
/ sizeof(ctx->ns_lookup_pool[0])));
|
||||||
|
return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
|
||||||
|
}
|
||||||
|
ctx->ns_lookup_pool[ctx->ns_lookup_pool_size++] = arg + 16;
|
||||||
|
}
|
||||||
|
return LIBC_WASI_PARSE_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
libc_wasi_init(wasm_module_t wasm_module, int argc, char **argv,
|
||||||
|
libc_wasi_parse_context_t *ctx)
|
||||||
|
{
|
||||||
|
wasm_runtime_set_wasi_args(wasm_module, ctx->dir_list, ctx->dir_list_size,
|
||||||
|
ctx->map_dir_list, ctx->map_dir_list_size,
|
||||||
|
ctx->env_list, ctx->env_list_size, argv, argc);
|
||||||
|
|
||||||
|
wasm_runtime_set_wasi_addr_pool(wasm_module, ctx->addr_pool,
|
||||||
|
ctx->addr_pool_size);
|
||||||
|
wasm_runtime_set_wasi_ns_lookup_pool(wasm_module, ctx->ns_lookup_pool,
|
||||||
|
ctx->ns_lookup_pool_size);
|
||||||
|
}
|
|
@ -250,7 +250,8 @@ handle_cmd_load_module(uint64 *args, uint32 argc)
|
||||||
|
|
||||||
if (total_size >= UINT32_MAX
|
if (total_size >= UINT32_MAX
|
||||||
|| !(enclave_module = (EnclaveModule *)os_mmap(
|
|| !(enclave_module = (EnclaveModule *)os_mmap(
|
||||||
NULL, (uint32)total_size, map_prot, map_flags))) {
|
NULL, (uint32)total_size, map_prot, map_flags,
|
||||||
|
os_get_invalid_handle()))) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"WASM module load failed: mmap memory failed.");
|
"WASM module load failed: mmap memory failed.");
|
||||||
*(void **)args_org = NULL;
|
*(void **)args_org = NULL;
|
||||||
|
|
|
@ -246,8 +246,12 @@ ifeq ($(CONFIG_INTERPRETERS_WAMR_LIBC_WASI),y)
|
||||||
CFLAGS += -DWASM_ENABLE_LIBC_WASI=1
|
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/src
|
||||||
CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/include
|
CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/include
|
||||||
|
CFLAGS += -I${SHARED_ROOT}/platform/common/libc-util
|
||||||
CSRCS += blocking_op.c
|
CSRCS += blocking_op.c
|
||||||
CSRCS += posix_socket.c
|
CSRCS += posix_socket.c
|
||||||
|
CSRCS += posix_file.c
|
||||||
|
CSRCS += posix_clock.c
|
||||||
|
CSRCS += libc_errno.c
|
||||||
CSRCS += libc_wasi_wrapper.c
|
CSRCS += libc_wasi_wrapper.c
|
||||||
VPATH += $(IWASM_ROOT)/libraries/libc-wasi
|
VPATH += $(IWASM_ROOT)/libraries/libc-wasi
|
||||||
CSRCS += posix.c
|
CSRCS += posix.c
|
||||||
|
@ -395,6 +399,7 @@ ASRCS += $(INVOKE_NATIVE)
|
||||||
|
|
||||||
VPATH += $(SHARED_ROOT)/platform/nuttx
|
VPATH += $(SHARED_ROOT)/platform/nuttx
|
||||||
VPATH += $(SHARED_ROOT)/platform/common/posix
|
VPATH += $(SHARED_ROOT)/platform/common/posix
|
||||||
|
VPATH += $(SHARED_ROOT)/platform/common/libc-util
|
||||||
VPATH += $(SHARED_ROOT)/mem-alloc
|
VPATH += $(SHARED_ROOT)/mem-alloc
|
||||||
VPATH += $(SHARED_ROOT)/mem-alloc/ems
|
VPATH += $(SHARED_ROOT)/mem-alloc/ems
|
||||||
VPATH += $(SHARED_ROOT)/utils
|
VPATH += $(SHARED_ROOT)/utils
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
#include "bh_read_file.h"
|
#include "bh_read_file.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
|
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
#include "../common/libc_wasi.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if BH_HAS_DLFCN
|
#if BH_HAS_DLFCN
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -69,24 +73,7 @@ print_help()
|
||||||
printf(" --disable-bounds-checks Disable bounds checks for memory accesses\n");
|
printf(" --disable-bounds-checks Disable bounds checks for memory accesses\n");
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
|
libc_wasi_print_help();
|
||||||
printf(" to the program, for example:\n");
|
|
||||||
printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
|
|
||||||
printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
|
||||||
printf(" to the program, for example:\n");
|
|
||||||
printf(" --dir=<dir1> --dir=<dir2>\n");
|
|
||||||
printf(" --map-dir=<guest::host> Grant wasi access to the given host directories\n");
|
|
||||||
printf(" to the program at a specific guest path, for example:\n");
|
|
||||||
printf(" --map-dir=<guest-path1::host-path1> --map-dir=<guest-path2::host-path2>\n");
|
|
||||||
printf(" --addr-pool=<addrs> Grant wasi access to the given network addresses in\n");
|
|
||||||
printf(" CIRD notation to the program, seperated with ',',\n");
|
|
||||||
printf(" for example:\n");
|
|
||||||
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
|
|
||||||
printf(" --allow-resolve=<domain> Allow the lookup of the specific domain name or domain\n");
|
|
||||||
printf(" name suffixes using a wildcard, for example:\n");
|
|
||||||
printf(" --allow-resolve=example.com # allow the lookup of the specific domain\n");
|
|
||||||
printf(" --allow-resolve=*.example.com # allow the lookup of all subdomains\n");
|
|
||||||
printf(" --allow-resolve=* # allow any lookup\n");
|
|
||||||
#endif
|
#endif
|
||||||
#if BH_HAS_DLFCN
|
#if BH_HAS_DLFCN
|
||||||
printf(" --native-lib=<lib> Register native libraries to the WASM module, which\n");
|
printf(" --native-lib=<lib> Register native libraries to the WASM module, which\n");
|
||||||
|
@ -207,8 +194,11 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (app_argc != 0) {
|
if (app_argc != 0) {
|
||||||
|
const char *exception;
|
||||||
wasm_application_execute_func(module_inst, app_argv[0],
|
wasm_application_execute_func(module_inst, app_argv[0],
|
||||||
app_argc - 1, app_argv + 1);
|
app_argc - 1, app_argv + 1);
|
||||||
|
if ((exception = wasm_runtime_get_exception(module_inst)))
|
||||||
|
printf("%s\n", exception);
|
||||||
}
|
}
|
||||||
free(app_argv);
|
free(app_argv);
|
||||||
}
|
}
|
||||||
|
@ -269,25 +259,6 @@ resolve_segue_flags(char *str_flags)
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_JIT != 0 */
|
#endif /* end of WASM_ENABLE_JIT != 0 */
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
|
||||||
static bool
|
|
||||||
validate_env_str(char *env)
|
|
||||||
{
|
|
||||||
char *p = env;
|
|
||||||
int key_len = 0;
|
|
||||||
|
|
||||||
while (*p != '\0' && *p != '=') {
|
|
||||||
key_len++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p != '=' || key_len == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BH_HAS_DLFCN
|
#if BH_HAS_DLFCN
|
||||||
struct native_lib {
|
struct native_lib {
|
||||||
void *handle;
|
void *handle;
|
||||||
|
@ -464,7 +435,37 @@ moudle_destroyer(uint8 *buffer, uint32 size)
|
||||||
|
|
||||||
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
||||||
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
||||||
|
#else
|
||||||
|
static void *
|
||||||
|
malloc_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
#endif
|
#endif
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
realloc_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
|
#endif
|
||||||
|
void *ptr, unsigned int size)
|
||||||
|
{
|
||||||
|
return realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
|
#endif
|
||||||
|
void *ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */
|
||||||
|
|
||||||
#if WASM_ENABLE_STATIC_PGO != 0
|
#if WASM_ENABLE_STATIC_PGO != 0
|
||||||
static void
|
static void
|
||||||
|
@ -574,16 +575,7 @@ main(int argc, char *argv[])
|
||||||
bool disable_bounds_checks = false;
|
bool disable_bounds_checks = false;
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
const char *dir_list[8] = { NULL };
|
libc_wasi_parse_context_t wasi_parse_ctx;
|
||||||
uint32 dir_list_size = 0;
|
|
||||||
const char *map_dir_list[8] = { NULL };
|
|
||||||
uint32 map_dir_list_size = 0;
|
|
||||||
const char *env_list[8] = { NULL };
|
|
||||||
uint32 env_list_size = 0;
|
|
||||||
const char *addr_pool[8] = { NULL };
|
|
||||||
uint32 addr_pool_size = 0;
|
|
||||||
const char *ns_lookup_pool[8] = { NULL };
|
|
||||||
uint32 ns_lookup_pool_size = 0;
|
|
||||||
#endif
|
#endif
|
||||||
#if BH_HAS_DLFCN
|
#if BH_HAS_DLFCN
|
||||||
const char *native_lib_list[8] = { NULL };
|
const char *native_lib_list[8] = { NULL };
|
||||||
|
@ -602,6 +594,10 @@ main(int argc, char *argv[])
|
||||||
int timeout_ms = -1;
|
int timeout_ms = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Process options. */
|
/* Process options. */
|
||||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||||
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
|
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
|
||||||
|
@ -705,80 +701,6 @@ main(int argc, char *argv[])
|
||||||
return print_help();
|
return print_help();
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_JIT != 0 */
|
#endif /* end of WASM_ENABLE_JIT != 0 */
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
|
||||||
else if (!strncmp(argv[0], "--dir=", 6)) {
|
|
||||||
if (argv[0][6] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (dir_list_size >= sizeof(dir_list) / sizeof(char *)) {
|
|
||||||
printf("Only allow max dir number %d\n",
|
|
||||||
(int)(sizeof(dir_list) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
dir_list[dir_list_size++] = argv[0] + 6;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[0], "--map-dir=", 10)) {
|
|
||||||
if (argv[0][10] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (map_dir_list_size >= sizeof(map_dir_list) / sizeof(char *)) {
|
|
||||||
printf("Only allow max map dir number %d\n",
|
|
||||||
(int)(sizeof(map_dir_list) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
map_dir_list[map_dir_list_size++] = argv[0] + 10;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[0], "--env=", 6)) {
|
|
||||||
char *tmp_env;
|
|
||||||
|
|
||||||
if (argv[0][6] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (env_list_size >= sizeof(env_list) / sizeof(char *)) {
|
|
||||||
printf("Only allow max env number %d\n",
|
|
||||||
(int)(sizeof(env_list) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
tmp_env = argv[0] + 6;
|
|
||||||
if (validate_env_str(tmp_env))
|
|
||||||
env_list[env_list_size++] = tmp_env;
|
|
||||||
else {
|
|
||||||
printf("Wasm parse env string failed: expect \"key=value\", "
|
|
||||||
"got \"%s\"\n",
|
|
||||||
tmp_env);
|
|
||||||
return print_help();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* TODO: parse the configuration file via --addr-pool-file */
|
|
||||||
else if (!strncmp(argv[0], "--addr-pool=", strlen("--addr-pool="))) {
|
|
||||||
/* like: --addr-pool=100.200.244.255/30 */
|
|
||||||
char *token = NULL;
|
|
||||||
|
|
||||||
if ('\0' == argv[0][12])
|
|
||||||
return print_help();
|
|
||||||
|
|
||||||
token = strtok(argv[0] + strlen("--addr-pool="), ",");
|
|
||||||
while (token) {
|
|
||||||
if (addr_pool_size >= sizeof(addr_pool) / sizeof(char *)) {
|
|
||||||
printf("Only allow max address number %d\n",
|
|
||||||
(int)(sizeof(addr_pool) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_pool[addr_pool_size++] = token;
|
|
||||||
token = strtok(NULL, ";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[0], "--allow-resolve=", 16)) {
|
|
||||||
if (argv[0][16] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (ns_lookup_pool_size
|
|
||||||
>= sizeof(ns_lookup_pool) / sizeof(ns_lookup_pool[0])) {
|
|
||||||
printf(
|
|
||||||
"Only allow max ns lookup number %d\n",
|
|
||||||
(int)(sizeof(ns_lookup_pool) / sizeof(ns_lookup_pool[0])));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
ns_lookup_pool[ns_lookup_pool_size++] = argv[0] + 16;
|
|
||||||
}
|
|
||||||
#endif /* WASM_ENABLE_LIBC_WASI */
|
|
||||||
#if BH_HAS_DLFCN
|
#if BH_HAS_DLFCN
|
||||||
else if (!strncmp(argv[0], "--native-lib=", 13)) {
|
else if (!strncmp(argv[0], "--native-lib=", 13)) {
|
||||||
if (argv[0][13] == '\0')
|
if (argv[0][13] == '\0')
|
||||||
|
@ -841,8 +763,22 @@ main(int argc, char *argv[])
|
||||||
patch);
|
patch);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
libc_wasi_parse_result_t result =
|
||||||
|
libc_wasi_parse(argv[0], &wasi_parse_ctx);
|
||||||
|
switch (result) {
|
||||||
|
case LIBC_WASI_PARSE_RESULT_OK:
|
||||||
|
continue;
|
||||||
|
case LIBC_WASI_PARSE_RESULT_NEED_HELP:
|
||||||
|
return print_help();
|
||||||
|
case LIBC_WASI_PARSE_RESULT_BAD_PARAM:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
return print_help();
|
return print_help();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
|
@ -861,9 +797,13 @@ main(int argc, char *argv[])
|
||||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||||
#else
|
#else
|
||||||
init_args.mem_alloc_type = Alloc_With_Allocator;
|
init_args.mem_alloc_type = Alloc_With_Allocator;
|
||||||
init_args.mem_alloc_option.allocator.malloc_func = malloc;
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
init_args.mem_alloc_option.allocator.realloc_func = realloc;
|
/* Set user data for the allocator is needed */
|
||||||
init_args.mem_alloc_option.allocator.free_func = free;
|
/* init_args.mem_alloc_option.allocator.user_data = user_data; */
|
||||||
|
#endif
|
||||||
|
init_args.mem_alloc_option.allocator.malloc_func = malloc_func;
|
||||||
|
init_args.mem_alloc_option.allocator.realloc_func = realloc_func;
|
||||||
|
init_args.mem_alloc_option.allocator.free_func = free_func;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
|
@ -908,8 +848,8 @@ main(int argc, char *argv[])
|
||||||
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
||||||
int map_flags = MMAP_MAP_32BIT;
|
int map_flags = MMAP_MAP_32BIT;
|
||||||
|
|
||||||
if (!(wasm_file_mapped =
|
if (!(wasm_file_mapped = os_mmap(NULL, (uint32)wasm_file_size, map_prot,
|
||||||
os_mmap(NULL, (uint32)wasm_file_size, map_prot, map_flags))) {
|
map_flags, os_get_invalid_handle()))) {
|
||||||
printf("mmap memory failed\n");
|
printf("mmap memory failed\n");
|
||||||
wasm_runtime_free(wasm_file_buf);
|
wasm_runtime_free(wasm_file_buf);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
@ -935,13 +875,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size,
|
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
|
||||||
map_dir_list, map_dir_list_size, env_list,
|
|
||||||
env_list_size, argv, argc);
|
|
||||||
|
|
||||||
wasm_runtime_set_wasi_addr_pool(wasm_module, addr_pool, addr_pool_size);
|
|
||||||
wasm_runtime_set_wasi_ns_lookup_pool(wasm_module, ns_lookup_pool,
|
|
||||||
ns_lookup_pool_size);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* instantiate the module */
|
/* instantiate the module */
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
cmake_minimum_required (VERSION 2.9)
|
cmake_minimum_required (VERSION 2.9)
|
||||||
|
|
||||||
project (iwasm C ASM CXX)
|
project (iwasm C ASM CXX)
|
||||||
enable_language(ASM_MASM)
|
|
||||||
# set (CMAKE_VERBOSE_MAKEFILE 1)
|
# set (CMAKE_VERBOSE_MAKEFILE 1)
|
||||||
|
|
||||||
set (WAMR_BUILD_PLATFORM "windows")
|
set (WAMR_BUILD_PLATFORM "windows")
|
||||||
|
@ -13,8 +12,6 @@ set (WAMR_BUILD_PLATFORM "windows")
|
||||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||||
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||||
|
|
||||||
set (CMAKE_C_STANDARD 99)
|
|
||||||
|
|
||||||
add_definitions(-DCOMPILING_WASM_RUNTIME_API=1)
|
add_definitions(-DCOMPILING_WASM_RUNTIME_API=1)
|
||||||
|
|
||||||
# Set WAMR_BUILD_TARGET, currently values supported:
|
# Set WAMR_BUILD_TARGET, currently values supported:
|
||||||
|
@ -96,6 +93,15 @@ if (WAMR_BUILD_DEBUG_INTERP EQUAL 1)
|
||||||
set (WAMR_BUILD_SIMD 0)
|
set (WAMR_BUILD_SIMD 0)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||||
|
set (CMAKE_C_STANDARD 11)
|
||||||
|
if (MSVC)
|
||||||
|
add_compile_options(/experimental:c11atomics)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set (CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
||||||
|
|
||||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||||
|
@ -147,3 +153,9 @@ target_link_libraries (libiwasm ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS})
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
target_link_libraries (libiwasm ws2_32)
|
target_link_libraries (libiwasm ws2_32)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
target_link_libraries(libiwasm ntdll)
|
||||||
|
|
||||||
|
target_link_libraries(iwasm ntdll)
|
||||||
|
endif()
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include "bh_read_file.h"
|
#include "bh_read_file.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
|
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
#include "../common/libc_wasi.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
static int app_argc;
|
static int app_argc;
|
||||||
static char **app_argv;
|
static char **app_argv;
|
||||||
|
|
||||||
|
@ -48,12 +52,7 @@ print_help()
|
||||||
printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
||||||
" that runs commands in the form of `FUNC ARG...`\n");
|
" that runs commands in the form of `FUNC ARG...`\n");
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
|
libc_wasi_print_help();
|
||||||
printf(" to the program, for example:\n");
|
|
||||||
printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
|
|
||||||
printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
|
||||||
printf(" to the program, for example:\n");
|
|
||||||
printf(" --dir=<dir1> --dir=<dir2>\n");
|
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
printf(" --module-path=<path> Indicate a module search path. default is current\n"
|
printf(" --module-path=<path> Indicate a module search path. default is current\n"
|
||||||
|
@ -141,7 +140,8 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||||
char *cmd;
|
char *cmd;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
while ((printf("webassembly> "), cmd = fgets(buffer, sizeof(buffer), stdin))
|
while ((printf("webassembly> "), fflush(stdout),
|
||||||
|
cmd = fgets(buffer, sizeof(buffer), stdin))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
bh_assert(cmd);
|
bh_assert(cmd);
|
||||||
n = strlen(cmd);
|
n = strlen(cmd);
|
||||||
|
@ -161,8 +161,11 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (app_argc != 0) {
|
if (app_argc != 0) {
|
||||||
|
const char *exception;
|
||||||
wasm_application_execute_func(module_inst, app_argv[0],
|
wasm_application_execute_func(module_inst, app_argv[0],
|
||||||
app_argc - 1, app_argv + 1);
|
app_argc - 1, app_argv + 1);
|
||||||
|
if ((exception = wasm_runtime_get_exception(module_inst)))
|
||||||
|
printf("%s\n", exception);
|
||||||
}
|
}
|
||||||
free(app_argv);
|
free(app_argv);
|
||||||
}
|
}
|
||||||
|
@ -170,28 +173,39 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
|
||||||
static bool
|
|
||||||
validate_env_str(char *env)
|
|
||||||
{
|
|
||||||
char *p = env;
|
|
||||||
int key_len = 0;
|
|
||||||
|
|
||||||
while (*p != '\0' && *p != '=') {
|
|
||||||
key_len++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p != '=' || key_len == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
||||||
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
|
||||||
|
#else
|
||||||
|
static void *
|
||||||
|
malloc_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
#endif
|
#endif
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
realloc_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
|
#endif
|
||||||
|
void *ptr, unsigned int size)
|
||||||
|
{
|
||||||
|
return realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_func(
|
||||||
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
|
void *user_data,
|
||||||
|
#endif
|
||||||
|
void *ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
static char *
|
static char *
|
||||||
|
@ -272,16 +286,17 @@ main(int argc, char *argv[])
|
||||||
bool is_repl_mode = false;
|
bool is_repl_mode = false;
|
||||||
bool is_xip_file = false;
|
bool is_xip_file = false;
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
const char *dir_list[8] = { NULL };
|
libc_wasi_parse_context_t wasi_parse_ctx;
|
||||||
uint32 dir_list_size = 0;
|
|
||||||
const char *env_list[8] = { NULL };
|
|
||||||
uint32 env_list_size = 0;
|
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
char *ip_addr = NULL;
|
char *ip_addr = NULL;
|
||||||
int instance_port = 0;
|
int instance_port = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Process options. */
|
/* Process options. */
|
||||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||||
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
|
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
|
||||||
|
@ -363,38 +378,6 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
|
||||||
else if (!strncmp(argv[0], "--dir=", 6)) {
|
|
||||||
if (argv[0][6] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (dir_list_size >= sizeof(dir_list) / sizeof(char *)) {
|
|
||||||
printf("Only allow max dir number %d\n",
|
|
||||||
(int)(sizeof(dir_list) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
dir_list[dir_list_size++] = argv[0] + 6;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[0], "--env=", 6)) {
|
|
||||||
char *tmp_env;
|
|
||||||
|
|
||||||
if (argv[0][6] == '\0')
|
|
||||||
return print_help();
|
|
||||||
if (env_list_size >= sizeof(env_list) / sizeof(char *)) {
|
|
||||||
printf("Only allow max env number %d\n",
|
|
||||||
(int)(sizeof(env_list) / sizeof(char *)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
tmp_env = argv[0] + 6;
|
|
||||||
if (validate_env_str(tmp_env))
|
|
||||||
env_list[env_list_size++] = tmp_env;
|
|
||||||
else {
|
|
||||||
printf("Wasm parse env string failed: expect \"key=value\", "
|
|
||||||
"got \"%s\"\n",
|
|
||||||
tmp_env);
|
|
||||||
return print_help();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WASM_ENABLE_LIBC_WASI */
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
|
else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
|
||||||
module_search_path = handle_module_path(argv[0]);
|
module_search_path = handle_module_path(argv[0]);
|
||||||
|
@ -430,8 +413,22 @@ main(int argc, char *argv[])
|
||||||
patch);
|
patch);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
libc_wasi_parse_result_t result =
|
||||||
|
libc_wasi_parse(argv[0], &wasi_parse_ctx);
|
||||||
|
switch (result) {
|
||||||
|
case LIBC_WASI_PARSE_RESULT_OK:
|
||||||
|
continue;
|
||||||
|
case LIBC_WASI_PARSE_RESULT_NEED_HELP:
|
||||||
|
return print_help();
|
||||||
|
case LIBC_WASI_PARSE_RESULT_BAD_PARAM:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
return print_help();
|
return print_help();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
|
@ -450,9 +447,13 @@ main(int argc, char *argv[])
|
||||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||||
#else
|
#else
|
||||||
init_args.mem_alloc_type = Alloc_With_Allocator;
|
init_args.mem_alloc_type = Alloc_With_Allocator;
|
||||||
init_args.mem_alloc_option.allocator.malloc_func = malloc;
|
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||||
init_args.mem_alloc_option.allocator.realloc_func = realloc;
|
/* Set user data for the allocator is needed */
|
||||||
init_args.mem_alloc_option.allocator.free_func = free;
|
/* init_args.mem_alloc_option.allocator.user_data = user_data; */
|
||||||
|
#endif
|
||||||
|
init_args.mem_alloc_option.allocator.malloc_func = malloc_func;
|
||||||
|
init_args.mem_alloc_option.allocator.realloc_func = realloc_func;
|
||||||
|
init_args.mem_alloc_option.allocator.free_func = free_func;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_JIT != 0
|
#if WASM_ENABLE_JIT != 0
|
||||||
|
@ -487,8 +488,8 @@ main(int argc, char *argv[])
|
||||||
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
|
||||||
int map_flags = MMAP_MAP_32BIT;
|
int map_flags = MMAP_MAP_32BIT;
|
||||||
|
|
||||||
if (!(wasm_file_mapped =
|
if (!(wasm_file_mapped = os_mmap(NULL, (uint32)wasm_file_size, map_prot,
|
||||||
os_mmap(NULL, (uint32)wasm_file_size, map_prot, map_flags))) {
|
map_flags, os_get_invalid_handle()))) {
|
||||||
printf("mmap memory failed\n");
|
printf("mmap memory failed\n");
|
||||||
wasm_runtime_free(wasm_file_buf);
|
wasm_runtime_free(wasm_file_buf);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
@ -514,8 +515,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 0,
|
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
|
||||||
env_list, env_list_size, argv, argc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* instantiate the module */
|
/* instantiate the module */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user