Merge pull request #2740 from bytecodealliance/dev/wasi-libc-windows

The implementation is already in a stage where it's possible to compile WAMR
with wasi libc enabled and run wasi modules without errors.
This commit is contained in:
Wenyong Huang 2023-11-10 16:58:31 +08:00 committed by GitHub
commit 71340b79a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 6559 additions and 2790 deletions

View File

@ -39,6 +39,16 @@ on:
# allow to be triggered manually
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
# at a time
concurrency:
@ -60,12 +70,14 @@ jobs:
"-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_DEBUG_INTERP=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:
- uses: actions/checkout@v3
- name: clone uvwasi library
if: ${{ !contains(matrix.build_options, '-DWAMR_BUILD_LIBC_UVWASI=0') }}
run: |
cd core/deps
git clone https://github.com/nodejs/uvwasi.git
@ -75,3 +87,50 @@ jobs:
mkdir build && cd build
cmake .. ${{ matrix.build_options }}
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

View File

@ -165,7 +165,11 @@ file (GLOB 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_DIR}/mem-alloc/mem_alloc.cmake)

View File

@ -388,6 +388,18 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
{
float32 f32 = strtof(argv[i], &endptr);
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] == '-') {
union ieee754_float u;
u.f = f32;
@ -422,6 +434,9 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
} u;
u.val = strtod(argv[i], &endptr);
if (isnan(u.val)) {
#ifdef _MSC_VER
u.val = nan("");
#endif
if (argv[i][0] == '-') {
union ieee754_double ud;
ud.d = u.val;
@ -585,7 +600,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
{
#if UINTPTR_MAX == UINT32_MAX
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
os_printf("extern:ref.null");
k++;
@ -598,7 +613,7 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
u.parts[1] = argv1[k + 1];
k += 2;
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
os_printf("extern:ref.null");
#endif

View File

@ -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 map_dir_count, const char *env_list[],
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);
@ -2792,9 +2792,9 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
wasi_args->env_count = env_count;
wasi_args->argv = argv;
wasi_args->argc = (uint32)argc;
wasi_args->stdio[0] = stdinfd;
wasi_args->stdio[1] = stdoutfd;
wasi_args->stdio[2] = stderrfd;
wasi_args->stdio[0] = (os_raw_file_handle)stdinfd;
wasi_args->stdio[1] = (os_raw_file_handle)stdoutfd;
wasi_args->stdio[2] = (os_raw_file_handle)stderrfd;
#if WASM_ENABLE_MULTI_MODULE != 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 *addr_pool[], uint32 addr_pool_size,
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
int stderrfd, char *error_buf, uint32 error_buf_size)
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
char *error_buf, uint32 error_buf_size)
{
WASIContext *wasi_ctx;
char *argv_buf = NULL;
@ -2908,7 +2909,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
bool argv_environ_inited = false;
bool addr_pool_inited = false;
__wasi_fd_t wasm_fd = 3;
int32 raw_fd;
os_file_handle file_handle;
char *path, resolved_path[PATH_MAX];
uint32 i;
@ -2978,15 +2979,19 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
}
addr_pool_inited = true;
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors.
*
* If -1 is given, use STDIN_FILENO (0), STDOUT_FILENO (1),
* STDERR_FILENO (2) respectively.
*/
if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0)
|| !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1)
|| !fd_table_insert_existing(curfds, 2,
(stderrfd != -1) ? stderrfd : 2)) {
os_file_handle stdin_file_handle = os_convert_stdin_handle(stdinfd);
os_file_handle stdout_file_handle = os_convert_stdout_handle(stdoutfd);
os_file_handle stderr_file_handle = os_convert_stderr_handle(stderrfd);
if (!os_is_handle_valid(&stdin_file_handle)
|| !os_is_handle_valid(&stdout_file_handle)
|| !os_is_handle_valid(&stderr_file_handle))
goto fail;
/* 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,
"Init wasi environment failed: init fd table failed");
goto fail;
@ -2994,7 +2999,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
wasm_fd = 3;
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 (error_buf)
snprintf(error_buf, error_buf_size,
@ -3003,22 +3008,31 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
goto fail;
}
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
if (raw_fd == -1) {
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
if (error != __WASI_ESUCCESS) {
if (error_buf)
snprintf(error_buf, error_buf_size,
"error while pre-opening directory %s: %d\n",
dir_list[i], errno);
dir_list[i], error);
goto fail;
}
if (!fd_table_insert_existing(curfds, wasm_fd, raw_fd)
|| !fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)) {
if (error_buf)
snprintf(
error_buf, error_buf_size,
"error while pre-opening directory %s: insertion failed\n",
dir_list[i]);
snprintf(error_buf, error_buf_size,
"error inserting preopen fd %u (directory %s) into fd "
"table",
(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;
}
}
@ -3053,7 +3067,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
goto fail;
}
path = realpath(map_host, resolved_path);
path = os_realpath(map_host, resolved_path);
if (!path) {
if (error_buf)
snprintf(error_buf, error_buf_size,
@ -3064,8 +3078,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
goto fail;
}
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
if (raw_fd == -1) {
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
if (error != __WASI_ESUCCESS) {
if (error_buf)
snprintf(error_buf, error_buf_size,
"error while pre-opening mapped directory %s: %d\n",
@ -3075,7 +3089,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
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)) {
if (error_buf)
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 *addr_pool[], uint32 addr_pool_size,
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
int stderrfd, char *error_buf, uint32 error_buf_size)
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
char *error_buf, uint32 error_buf_size)
{
WASIContext *ctx;
uvwasi_t *uvwasi;

View File

@ -15,7 +15,6 @@
#if WASM_ENABLE_LIBC_WASI != 0
#if WASM_ENABLE_UVWASI == 0
#include "wasmtime_ssp.h"
#include "posix.h"
#else
#include "uvwasi.h"
@ -863,7 +862,7 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
uint32 dir_count, const char *map_dir_list[],
uint32 map_dir_count, const char *env_list[],
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 */
WASM_RUNTIME_API_EXTERN void
@ -891,8 +890,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
const char *env[], uint32 env_count,
const char *addr_pool[], uint32 addr_pool_size,
const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
int stderrfd, char *error_buf, uint32 error_buf_size);
char *argv[], uint32 argc, os_raw_file_handle stdinfd,
os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
char *error_buf, uint32 error_buf_size);
void
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst);

View File

@ -432,26 +432,31 @@ wasm_runtime_get_module_hash(wasm_module_t module);
* @param env_count The number of elements in env.
* @param argv The list of command line arguments.
* @param argc The number of elements in argv.
* @param stdinfd The host file descriptor to back WASI STDIN_FILENO.
* If -1 is specified, STDIN_FILENO is used.
* @param stdoutfd The host file descriptor to back WASI STDOUT_FILENO.
* If -1 is specified, STDOUT_FILENO is used.
* @param stderrfd The host file descriptor to back WASI STDERR_FILENO.
* If -1 is specified, STDERR_FILENO is used.
* @param stdin_handle The raw host handle to back WASI STDIN_FILENO.
* If an invalid handle is specified (e.g. -1 on POSIX,
* INVALID_HANDLE_VALUE on Windows), the platform default
* for STDIN is used.
* @param stdoutfd The raw host handle to back WASI STDOUT_FILENO.
* 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_set_wasi_args_ex(wasm_module_t module,
const char *dir_list[], uint32_t dir_count,
const char *map_dir_list[], uint32_t map_dir_count,
const char *env[], uint32_t env_count,
char *argv[], int argc,
int stdinfd, int stdoutfd, int stderrfd);
char *argv[], int argc, int64_t stdinfd,
int64_t stdoutfd, int64_t stderrfd);
/**
* Set WASI parameters.
*
* Same as wasm_runtime_set_wasi_args_ex with stdinfd = -1, stdoutfd = -1,
* stderrfd = -1.
* Same as wasm_runtime_set_wasi_args_ex but with default stdio handles
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_wasi_args(wasm_module_t module,

View File

@ -350,7 +350,7 @@ typedef struct WASIArguments {
uint32 ns_lookup_count;
char **argv;
uint32 argc;
int stdio[3];
os_raw_file_handle stdio[3];
} WASIArguments;
#endif

View File

@ -330,8 +330,9 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
}
#ifdef BH_PLATFORM_WINDOWS
if (!os_mem_commit(mapped_mem, memory_data_size,
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
if (memory_data_size > 0
&& !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");
os_munmap(mapped_mem, map_size);
goto fail1;

View File

@ -0,0 +1,3 @@
{
"name": "WAMR lib-socket tests"
}

View File

@ -7,6 +7,7 @@
#include "bh_platform.h"
#include "wasm_export.h"
#include "wasm_runtime_common.h"
#include "wasmtime_ssp.h"
#if WASM_ENABLE_THREAD_MGR != 0
#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)))
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
@ -206,7 +207,7 @@ wasi_clock_time_get(wasm_exec_env_t exec_env,
if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
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

View File

@ -6,7 +6,6 @@
#ifndef _LIBC_WASI_WRAPPER_H
#define _LIBC_WASI_WRAPPER_H
#include "wasmtime_ssp.h"
#include "posix.h"
#ifdef __cplusplus

View File

@ -8,99 +8,68 @@
#include "ssp_config.h"
#include "blocking_op.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd)
__wasi_errno_t
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
bool is_stdio)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
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);
return ret;
}
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
__wasi_errno_t
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
size_t *nwritten)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
ssize_t ret = readv(fd, iov, iovcnt);
__wasi_errno_t error = os_writev(handle, iov, iovcnt, nwritten);
wasm_runtime_end_blocking_op(exec_env);
return ret;
return error;
}
#if CONFIG_HAS_PREADV
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
__wasi_errno_t
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nwritten)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
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);
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
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;
}
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode)
__wasi_errno_t
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)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
return __WASI_EINTR;
}
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);
return ret;
return error;
}

View File

@ -6,26 +6,24 @@
#include "bh_platform.h"
#include "wasm_export.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd);
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset);
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset);
__wasi_errno_t
blocking_op_close(wasm_exec_env_t exec_env, os_file_handle handle,
bool is_stdio);
__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);
__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);
__wasi_errno_t
blocking_op_writev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
size_t *nwritten);
__wasi_errno_t
blocking_op_pwritev(wasm_exec_env_t exec_env, os_file_handle handle,
const struct __wasi_ciovec_t *iov, int iovcnt,
__wasi_filesize_t offset, size_t *nwritten);
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
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,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size);
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode);
__wasi_errno_t
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);

View File

@ -49,7 +49,7 @@
/* Mutex that uses the lock annotations. */
struct LOCKABLE mutex {
pthread_mutex_t object;
korp_mutex object;
};
/* clang-format off */
@ -60,69 +60,71 @@ struct LOCKABLE mutex {
static inline bool
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
mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock)
{
pthread_mutex_destroy(&lock->object);
os_mutex_destroy(&lock->object);
}
static inline void
mutex_lock(struct mutex *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
{
pthread_mutex_lock(&lock->object);
os_mutex_lock(&lock->object);
}
static inline void
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. */
struct LOCKABLE rwlock {
pthread_rwlock_t object;
korp_rwlock object;
};
static inline bool
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
rwlock_rdlock(struct rwlock *lock) LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS
{
pthread_rwlock_rdlock(&lock->object);
os_rwlock_rdlock(&lock->object);
}
static inline void
rwlock_wrlock(struct rwlock *lock) LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
{
pthread_rwlock_wrlock(&lock->object);
os_rwlock_wrlock(&lock->object);
}
static inline void
rwlock_unlock(struct rwlock *lock) UNLOCKS(*lock) NO_LOCK_ANALYSIS
{
pthread_rwlock_unlock(&lock->object);
os_rwlock_unlock(&lock->object);
}
static inline void
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. */
struct LOCKABLE cond {
pthread_cond_t object;
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
korp_cond object;
#if !CONFIG_HAS_CLOCK_NANOSLEEP \
&& (!CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK \
|| !CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
clockid_t clock;
#endif
};
@ -147,43 +149,49 @@ cond_init_monotonic(struct cond *cond)
fail:
pthread_condattr_destroy(&attr);
#else
if (pthread_cond_init(&cond->object, NULL) != 0)
if (os_cond_init(&cond->object) != 0)
return false;
ret = true;
#endif
#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_MONOTONIC;
#endif
return ret;
}
static inline bool
cond_init_realtime(struct cond *cond)
{
if (pthread_cond_init(&cond->object, NULL) != 0)
if (os_cond_init(&cond->object) != 0)
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;
#endif
return true;
}
static inline void
cond_destroy(struct cond *cond)
{
pthread_cond_destroy(&cond->object);
os_cond_destroy(&cond->object);
}
static inline void
cond_signal(struct cond *cond)
{
pthread_cond_signal(&cond->object);
os_cond_signal(&cond->object);
}
#if !CONFIG_HAS_CLOCK_NANOSLEEP
static inline bool
cond_timedwait(struct cond *cond, struct mutex *lock, uint64_t timeout,
bool abstime) REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
@ -259,7 +267,7 @@ static inline void
cond_wait(struct cond *cond, struct mutex *lock)
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS
{
pthread_cond_wait(&cond->object, &lock->object);
os_cond_wait(&cond->object, &lock->object);
}
#endif

View File

@ -60,7 +60,8 @@ struct addr_pool {
bool
fd_table_init(struct fd_table *);
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
fd_prestats_init(struct fd_prestats *);
bool

View File

@ -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
static int urandom;

View File

@ -47,75 +47,19 @@
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
#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__)
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
#else
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
#endif
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32) \
&& !defined(__COSMOPOLITAN__)
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
#else
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
#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)
/* Clang's __GNUC_PREREQ macro has a different meaning than GCC one,
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
#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

View File

@ -64,4 +64,8 @@ int signbit(double x);
int isnan(double x);
/* clang-format on */
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#endif /* end of _BH_PLATFORM_H */

View File

@ -56,6 +56,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -145,6 +146,10 @@ preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset);
ssize_t
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#ifdef __cplusplus
}
#endif

View 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;
}

View 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 */

View File

@ -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)

View File

@ -5,4 +5,14 @@ set (PLATFORM_COMMON_POSIX_DIR ${CMAKE_CURRENT_LIST_DIR})
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} )

View 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -329,6 +329,61 @@ os_cond_broadcast(korp_cond *cond)
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
os_thread_join(korp_tid thread, void **value_ptr)
{

View File

@ -63,6 +63,10 @@ typedef sem_t korp_sem;
#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 defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#define os_writegsbase(base_addr) \

View File

@ -58,6 +58,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -108,6 +109,10 @@ os_sigreturn();
void
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;
#ifdef __cplusplus
}
#endif

View File

@ -39,6 +39,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef unsigned int korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -108,6 +109,10 @@ typedef unsigned int korp_sem;
#define DT_LNK DTYPE_LINK
#define DT_SOCK DTYPE_SOCK
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#ifdef __cplusplus
}
#endif

View File

@ -57,6 +57,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -65,6 +66,10 @@ typedef sem_t korp_sem;
#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 defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \

View File

@ -7,6 +7,7 @@
#define PLATFORM_API_EXTENSION_H
#include "platform_common.h"
#include "platform_wasi_types.h"
/**
* The related data structures should be defined
* in platform_internal.h
@ -238,6 +239,56 @@ os_cond_signal(korp_cond *cond);
int
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
* 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
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
}
#endif

View 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 */

View File

@ -50,6 +50,7 @@ typedef pthread_t korp_thread;
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_rwlock_t korp_rwlock;
typedef unsigned int korp_sem;
#ifndef SGX_DISABLE_PTHREAD
@ -68,6 +69,10 @@ strcpy(char *dest, const char *src);
#define os_memory_order_seq_cst __ATOMIC_SEQ_CST
#define os_atomic_thread_fence __atomic_thread_fence
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#ifdef __cplusplus
}
#endif

View File

@ -7,7 +7,6 @@
#define _LIBC_WASI_SGX_PFS_H
#include "bh_hashmap.h"
#include "wasmtime_ssp.h"
#ifdef __cplusplus
extern "C" {

View File

@ -213,4 +213,69 @@ os_thread_get_stack_boundary()
void
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;
}

View File

@ -20,16 +20,23 @@ if (NOT BUILD_UNTRUST_PART EQUAL 1)
${SGX_SDK_DIR}/include/libcxx)
endif ()
if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
add_definitions(-DSGX_DISABLE_WASI)
endif ()
if (NOT WAMR_BUILD_THREAD_MGR EQUAL 1)
add_definitions(-DSGX_DISABLE_PTHREAD)
endif ()
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)
set (PLATFORM_SHARED_SOURCE ${source_all})

View File

@ -55,6 +55,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -121,6 +122,10 @@ os_sigreturn();
void
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;
#ifdef __cplusplus
}
#endif

View File

@ -41,6 +41,7 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -129,6 +130,10 @@ fdopendir(int fd);
void
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;
#ifdef __cplusplus
}
#endif

View File

@ -10,5 +10,11 @@ include_directories(${PLATFORM_SHARED_DIR}/../include)
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})

View File

@ -52,6 +52,10 @@ typedef struct korp_cond {
#define os_printf printf
#define os_vprintf vprintf
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#if WA_MATH
/* clang-format off */
/* math functions which are not provided by os*/

View File

@ -45,4 +45,8 @@ typedef rt_int16_t int16_t;
typedef rt_uint64_t uint64_t;
typedef rt_int64_t int64_t;
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#endif /* RTTHREAD_PLATFORM_INTERNAL_H */

View File

@ -54,12 +54,17 @@ typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef pthread_rwlock_t korp_rwlock;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#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 defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64)

View File

@ -25,10 +25,14 @@
#include <stdint.h>
#include <malloc.h>
#include <process.h>
#include <winapifamily.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <basetsd.h>
#include <signal.h>
#include "platform_wasi_types.h"
#ifdef __cplusplus
extern "C" {
@ -57,6 +61,11 @@ typedef void *korp_tid;
typedef void *korp_mutex;
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
* 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;
} korp_cond;
#define bh_socket_t SOCKET
unsigned
os_getpagesize();
void *
@ -131,6 +138,55 @@ bh_atomic_thread_fence(int mem_order);
#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
#ifdef __cplusplus
}
#endif

View File

@ -13,6 +13,13 @@ include_directories(${PLATFORM_SHARED_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c
${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})
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)

View File

@ -14,8 +14,8 @@ void
bh_atomic_thread_fence(int mem_order)
{
std::memory_order order =
(std::memory_order)(std::memory_order::memory_order_relaxed + mem_order
- os_memory_order_relaxed);
(std::memory_order)((int)std::memory_order::memory_order_relaxed
+ mem_order - os_memory_order_relaxed);
std::atomic_thread_fence(order);
}

View 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,
&current_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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,22 @@
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
init_winsock()
{
@ -45,6 +61,17 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
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) {
af = AF_INET;
}
@ -54,18 +81,24 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
}
if (is_tcp) {
*sock = socket(af, SOCK_STREAM, IPPROTO_TCP);
(*sock)->raw.socket = socket(af, SOCK_STREAM, IPPROTO_TCP);
}
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
os_socket_bind(bh_socket_t socket, const char *host, int *port)
{
CHECK_VALID_SOCKET_HANDLE(socket);
struct sockaddr_in addr;
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_family = AF_INET;
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
ret = bind(socket->raw.socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
goto fail;
}
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());
goto fail;
}
@ -98,10 +131,12 @@ fail:
int
os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
{
CHECK_VALID_SOCKET_HANDLE(socket);
DWORD tv = (DWORD)(timeout_us / 1000UL);
if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv,
sizeof(tv))
if (setsockopt(socket->raw.socket, SOL_SOCKET, SO_RCVTIMEO,
(const char *)&tv, sizeof(tv))
!= 0) {
return BHT_ERROR;
}
@ -112,7 +147,9 @@ os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
int
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());
return BHT_ERROR;
}
@ -124,12 +161,26 @@ int
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
unsigned int *addrlen)
{
CHECK_VALID_SOCKET_HANDLE(server_sock);
struct sockaddr addr_tmp;
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());
return BHT_ERROR;
}
@ -140,13 +191,17 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
int
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
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -155,13 +210,17 @@ os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
int
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
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
int flags, const bh_sockaddr_t *dest_addr)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -170,14 +229,21 @@ os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
int
os_socket_close(bh_socket_t socket)
{
closesocket(socket);
CHECK_VALID_SOCKET_HANDLE(socket);
closesocket(socket->raw.socket);
BH_FREE(socket);
return BHT_OK;
}
int
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;
}
@ -206,6 +272,16 @@ os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
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
os_socket_addr_resolve(const char *host, const char *service,
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
os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -228,6 +306,8 @@ os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
int
os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -236,6 +316,8 @@ os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
int
os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -244,6 +326,8 @@ os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
int
os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -252,6 +336,8 @@ os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
int
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -260,6 +346,8 @@ os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
int
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -268,6 +356,8 @@ os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
int
os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -276,6 +366,8 @@ os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
int
os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -284,6 +376,8 @@ os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
int
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -292,6 +386,8 @@ os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
int
os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -300,6 +396,8 @@ os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
int
os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -308,6 +406,8 @@ os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
int
os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -316,6 +416,8 @@ os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -324,6 +426,8 @@ os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
int
os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -332,6 +436,8 @@ os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -340,6 +446,8 @@ os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
int
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -348,6 +456,8 @@ os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -356,6 +466,8 @@ os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
int
os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -364,6 +476,8 @@ os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
int
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -372,6 +486,8 @@ os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
int
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -380,6 +496,8 @@ os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -388,6 +506,8 @@ os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
int
os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -396,6 +516,8 @@ os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -404,6 +526,8 @@ os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
int
os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -412,6 +536,8 @@ os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
int
os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -420,6 +546,8 @@ os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
int
os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -428,6 +556,8 @@ os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
int
os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -436,6 +566,8 @@ os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
int
os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -444,6 +576,8 @@ os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
int
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -452,6 +586,8 @@ os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
int
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -462,6 +598,8 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
bh_ip_addr_buffer_t *imr_multiaddr,
uint32_t imr_interface, bool is_ipv6)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -472,6 +610,8 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
bh_ip_addr_buffer_t *imr_multiaddr,
uint32_t imr_interface, bool is_ipv6)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -480,6 +620,8 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
int
os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -488,6 +630,8 @@ os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
int
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -496,6 +640,8 @@ os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
int
os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -504,6 +650,8 @@ os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
int
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -512,6 +660,8 @@ os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
int
os_socket_set_ipv6_only(bh_socket_t socket, bool option)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -520,6 +670,8 @@ os_socket_set_ipv6_only(bh_socket_t socket, bool option)
int
os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -528,6 +680,8 @@ os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
int
os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
@ -536,6 +690,8 @@ os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
int
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
{
CHECK_VALID_SOCKET_HANDLE(socket);
errno = ENOSYS;
return BHT_ERROR;
}

View File

@ -541,6 +541,62 @@ os_mutex_unlock(korp_mutex *mutex)
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
os_cond_init(korp_cond *cond)
{

View 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

View 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 */

View File

@ -148,4 +148,8 @@ void
set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func,
exec_mem_free_func_t free_func);
typedef int os_file_handle;
typedef DIR *os_dir_stream;
typedef int os_raw_file_handle;
#endif

View 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);
}

View File

@ -246,8 +246,12 @@ ifeq ($(CONFIG_INTERPRETERS_WAMR_LIBC_WASI),y)
CFLAGS += -DWASM_ENABLE_LIBC_WASI=1
CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/src
CFLAGS += -I$(IWASM_ROOT)/libraries/libc-wasi/sandboxed-system-primitives/include
CFLAGS += -I${SHARED_ROOT}/platform/common/libc-util
CSRCS += blocking_op.c
CSRCS += posix_socket.c
CSRCS += posix_file.c
CSRCS += posix_clock.c
CSRCS += libc_errno.c
CSRCS += libc_wasi_wrapper.c
VPATH += $(IWASM_ROOT)/libraries/libc-wasi
CSRCS += posix.c
@ -387,6 +391,7 @@ ASRCS += $(INVOKE_NATIVE)
VPATH += $(SHARED_ROOT)/platform/nuttx
VPATH += $(SHARED_ROOT)/platform/common/posix
VPATH += $(SHARED_ROOT)/platform/common/libc-util
VPATH += $(SHARED_ROOT)/mem-alloc
VPATH += $(SHARED_ROOT)/mem-alloc/ems
VPATH += $(SHARED_ROOT)/utils

View File

@ -14,6 +14,10 @@
#include "bh_read_file.h"
#include "wasm_export.h"
#if WASM_ENABLE_LIBC_WASI != 0
#include "../common/libc_wasi.c"
#endif
#if BH_HAS_DLFCN
#include <dlfcn.h>
#endif
@ -69,24 +73,7 @@ print_help()
printf(" --disable-bounds-checks Disable bounds checks for memory accesses\n");
#endif
#if WASM_ENABLE_LIBC_WASI != 0
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");
libc_wasi_print_help();
#endif
#if BH_HAS_DLFCN
printf(" --native-lib=<lib> Register native libraries to the WASM module, which\n");
@ -272,25 +259,6 @@ resolve_segue_flags(char *str_flags)
}
#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
struct native_lib {
void *handle;
@ -607,16 +575,7 @@ main(int argc, char *argv[])
bool disable_bounds_checks = false;
#endif
#if WASM_ENABLE_LIBC_WASI != 0
const char *dir_list[8] = { NULL };
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;
libc_wasi_parse_context_t wasi_parse_ctx;
#endif
#if BH_HAS_DLFCN
const char *native_lib_list[8] = { NULL };
@ -635,6 +594,10 @@ main(int argc, char *argv[])
int timeout_ms = -1;
#endif
#if WASM_ENABLE_LIBC_WASI != 0
memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx));
#endif
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
@ -738,80 +701,6 @@ main(int argc, char *argv[])
return print_help();
}
#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
else if (!strncmp(argv[0], "--native-lib=", 13)) {
if (argv[0][13] == '\0')
@ -874,8 +763,22 @@ main(int argc, char *argv[])
patch);
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();
#endif
}
}
if (argc == 0)
@ -972,13 +875,7 @@ main(int argc, char *argv[])
}
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size,
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);
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
#endif
/* instantiate the module */

View File

@ -4,7 +4,6 @@
cmake_minimum_required (VERSION 2.9)
project (iwasm C ASM CXX)
enable_language(ASM_MASM)
# set (CMAKE_VERBOSE_MAKEFILE 1)
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_CXX_FLAGS "")
set (CMAKE_C_STANDARD 99)
add_definitions(-DCOMPILING_WASM_RUNTIME_API=1)
# Set WAMR_BUILD_TARGET, currently values supported:
@ -96,6 +93,15 @@ if (WAMR_BUILD_DEBUG_INTERP EQUAL 1)
set (WAMR_BUILD_SIMD 0)
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}/../../..)
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)
target_link_libraries (libiwasm ws2_32)
endif ()
if (WIN32)
target_link_libraries(libiwasm ntdll)
target_link_libraries(iwasm ntdll)
endif()

View File

@ -10,6 +10,10 @@
#include "bh_read_file.h"
#include "wasm_export.h"
#if WASM_ENABLE_LIBC_WASI != 0
#include "../common/libc_wasi.c"
#endif
static int app_argc;
static char **app_argv;
@ -48,12 +52,7 @@ print_help()
printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n");
#if WASM_ENABLE_LIBC_WASI != 0
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");
libc_wasi_print_help();
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
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;
size_t n;
while ((printf("webassembly> "), cmd = fgets(buffer, sizeof(buffer), stdin))
while ((printf("webassembly> "), fflush(stdout),
cmd = fgets(buffer, sizeof(buffer), stdin))
!= NULL) {
bh_assert(cmd);
n = strlen(cmd);
@ -173,25 +173,6 @@ app_instance_repl(wasm_module_inst_t module_inst)
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
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
#else
@ -305,16 +286,17 @@ main(int argc, char *argv[])
bool is_repl_mode = false;
bool is_xip_file = false;
#if WASM_ENABLE_LIBC_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32 env_list_size = 0;
libc_wasi_parse_context_t wasi_parse_ctx;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
char *ip_addr = NULL;
int instance_port = 0;
#endif
#if WASM_ENABLE_LIBC_WASI != 0
memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx));
#endif
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
@ -396,38 +378,6 @@ main(int argc, char *argv[])
}
}
#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
else if (!strncmp(argv[0], MODULE_PATH, strlen(MODULE_PATH))) {
module_search_path = handle_module_path(argv[0]);
@ -463,8 +413,22 @@ main(int argc, char *argv[])
patch);
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();
#endif
}
}
if (argc == 0)
@ -551,8 +515,7 @@ main(int argc, char *argv[])
}
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_set_wasi_args(wasm_module, dir_list, dir_list_size, NULL, 0,
env_list, env_list_size, argv, argc);
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
#endif
/* instantiate the module */

View File

@ -0,0 +1,51 @@
{
"WASI C tests": {
"fdopendir-with-access": "Not implemented",
"lseek": "Not implemented"
},
"WASI Rust tests": {
"dangling_symlink": "Not implemented",
"directory_seek": "Not implemented",
"dir_fd_op_failures": "Not implemented",
"fd_advise": "Not implemented",
"fd_fdstat_set_rights": "Not implemented",
"fd_filestat_set": "Not implemented",
"fd_flags_set": "Not implemented",
"fd_readdir": "Not implemented",
"file_allocate": "Not implemented",
"file_seek_tell": "Not implemented",
"file_truncation": "Not implemented",
"nofollow_errors": "Not implemented",
"path_exists": "Not implemented",
"path_filestat": "Not implemented",
"path_link": "Not implemented",
"path_open_preopen": "Not implemented",
"path_rename": "Not implemented",
"path_rename_dir_trailing_slashes": "Not implemented",
"path_symlink_trailing_slashes": "Not implemented",
"poll_oneoff_stdio": "Not implemented",
"readlink": "Not implemented (path_symlink)",
"symlink_create": "Not implemented",
"symlink_filestat": "Not implemented",
"symlink_loop": "Not implemented",
"truncation_rights": "Not implemented"
},
"WASI threads proposal": {
"wasi_threads_exit_main_wasi_read": "Blocking ops not implemented",
"wasi_threads_exit_nonmain_wasi_read": "Blocking ops not implemented",
"wasi_threads_return_main_wasi_read": "Blocking ops not implemented",
"wasi_threads_return_main_wasi": "Blocking ops not implemented",
"wasi_threads_exit_nonmain_wasi": "Blocking ops not implemented",
"wasi_threads_exit_main_wasi": "Blocking ops not implemented"
},
"WAMR lib-socket tests": {
"nslookup": "Not implemented",
"tcp_udp": "Not implemented"
},
"lib-wasi-threads tests": {
"nonmain_proc_exit_sleep": "poll_oneoff not implemented",
"main_proc_exit_sleep": "poll_oneoff not implemented",
"main_trap_sleep": "poll_oneoff not implemented",
"nonmain_trap_sleep": "poll_oneoff not implemented"
}
}

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project (basic)
else()
project (basic C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project (iwasm)
else()
project (iwasm C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project (inst-context)
else()
project (inst-context C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project (inst-context)
else()
project (inst-context C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project(ref-types)
else()
project (ref-types C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################

View File

@ -9,7 +9,6 @@ if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project(c-api)
else()
project (c-api C ASM)
enable_language (ASM_MASM)
endif()
if(NOT CMAKE_BUILD_TYPE)

View File

@ -6,7 +6,7 @@
import argparse
import multiprocessing as mp
import os
import platform
import pathlib
import subprocess
import sys
@ -28,12 +28,26 @@ To run a single GC case:
--aot-compiler wamrc --gc spec/test/core/xxx.wast
"""
PLATFORM_NAME = os.uname().sysname.lower()
IWASM_CMD = "../../../product-mini/platforms/" + PLATFORM_NAME + "/build/iwasm"
def exe_file_path(base_path: str) -> str:
if platform.system().lower() == "windows":
base_path += ".exe"
return base_path
def get_iwasm_cmd(platform: str) -> str:
build_path = "../../../product-mini/platforms/" + platform + "/build/"
exe_name = "iwasm"
if platform == "windows":
build_path += "RelWithDebInfo/"
return exe_file_path(build_path + exe_name)
PLATFORM_NAME = platform.uname().system.lower()
IWASM_CMD = get_iwasm_cmd(PLATFORM_NAME)
IWASM_SGX_CMD = "../../../product-mini/platforms/linux-sgx/enclave-sample/iwasm"
IWASM_QEMU_CMD = "iwasm"
SPEC_TEST_DIR = "spec/test/core"
WAST2WASM_CMD = "./wabt/out/gcc/Release/wat2wasm"
WAST2WASM_CMD = exe_file_path("./wabt/out/gcc/Release/wat2wasm")
SPEC_INTERPRETER_CMD = "spec/interpreter/wasm"
WAMRC_CMD = "../../../wamr-compiler/build/wamrc"
@ -146,8 +160,9 @@ def test_case(
qemu_flag=False,
qemu_firmware="",
log="",
no_pty=False
):
CMD = ["python3", "runtest.py"]
CMD = [sys.executable, "runtest.py"]
CMD.append("--wast2wasm")
CMD.append(WAST2WASM_CMD if not gc_flag else SPEC_INTERPRETER_CMD)
CMD.append("--interpreter")
@ -157,6 +172,8 @@ def test_case(
CMD.append(IWASM_QEMU_CMD)
else:
CMD.append(IWASM_CMD)
if no_pty:
CMD.append("--no-pty")
CMD.append("--aot-compiler")
CMD.append(WAMRC_CMD)
@ -261,6 +278,7 @@ def test_suite(
qemu_flag=False,
qemu_firmware="",
log="",
no_pty=False,
):
suite_path = pathlib.Path(SPEC_TEST_DIR).resolve()
if not suite_path.exists():
@ -322,6 +340,7 @@ def test_suite(
qemu_flag,
qemu_firmware,
log,
no_pty,
],
)
@ -359,6 +378,7 @@ def test_suite(
qemu_flag,
qemu_firmware,
log,
no_pty,
)
successful_case += 1
except Exception as e:
@ -480,6 +500,8 @@ def main():
nargs="*",
help=f"Specify all wanted cases. If not the script will go through all cases under {SPEC_TEST_DIR}",
)
parser.add_argument('--no-pty', action='store_true',
help="Use direct pipes instead of pseudo-tty")
options = parser.parse_args()
@ -509,6 +531,7 @@ def main():
options.qemu_flag,
options.qemu_firmware,
options.log,
options.no_pty
)
end = time.time_ns()
print(
@ -532,6 +555,7 @@ def main():
options.qemu_flag,
options.qemu_firmware,
options.log,
options.no_pty,
)
else:
ret = True

View File

@ -5,22 +5,21 @@ from __future__ import print_function
import argparse
import array
import atexit
import fcntl
import math
import os
# Pseudo-TTY and terminal manipulation
import pty
import re
import shutil
import struct
import subprocess
import sys
import tempfile
import termios
import time
import threading
import traceback
from select import select
from queue import Queue
from subprocess import PIPE, STDOUT, Popen
from typing import BinaryIO, Optional, Tuple
if sys.version_info[0] == 2:
IS_PY_3 = False
@ -52,6 +51,10 @@ def log(data, end='\n'):
print(data, end=end)
sys.stdout.flush()
def create_tmp_file(suffix: str) -> str:
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp_file:
return tmp_file.name
# TODO: do we need to support '\n' too
import platform
@ -62,6 +65,34 @@ else:
sep = "\r\n"
rundir = None
class AsyncStreamReader:
def __init__(self, stream: BinaryIO) -> None:
self._queue = Queue()
self._reader_thread = threading.Thread(
daemon=True,
target=AsyncStreamReader._stdout_reader,
args=(self._queue, stream))
self._reader_thread.start()
def read(self) -> Optional[bytes]:
return self._queue.get()
def cleanup(self) -> None:
self._reader_thread.join()
@staticmethod
def _stdout_reader(queue: Queue, stdout: BinaryIO) -> None:
while True:
try:
queue.put(stdout.read(1))
except ValueError as e:
if stdout.closed:
queue.put(None)
break
raise e
class Runner():
def __init__(self, args, no_pty=False):
self.no_pty = no_pty
@ -77,11 +108,14 @@ class Runner():
if no_pty:
self.process = Popen(args, bufsize=0,
stdin=PIPE, stdout=PIPE, stderr=STDOUT,
preexec_fn=os.setsid,
env=env)
self.stdin = self.process.stdin
self.stdout = self.process.stdout
else:
import fcntl
# Pseudo-TTY and terminal manipulation
import pty
import termios
# Use tty to setup an interactive environment
master, slave = pty.openpty()
@ -101,35 +135,53 @@ class Runner():
self.stdin = os.fdopen(master, 'r+b', 0)
self.stdout = self.stdin
if platform.system().lower() == "windows":
self._stream_reader = AsyncStreamReader(self.stdout)
else:
self._stream_reader = None
self.buf = ""
def _read_stdout_byte(self) -> Tuple[bool, Optional[bytes]]:
if self._stream_reader:
return True, self._stream_reader.read()
else:
# select doesn't work on file descriptors on Windows.
# however, this method is much faster than using
# queue, so we keep it for non-windows platforms.
[outs,_,_] = select([self.stdout], [], [], 1)
if self.stdout in outs:
return True, self.stdout.read(1)
else:
return False, None
def read_to_prompt(self, prompts, timeout):
wait_until = time.time() + timeout
while time.time() < wait_until:
[outs,_,_] = select([self.stdout], [], [], 1)
if self.stdout in outs:
read_byte = self.stdout.read(1)
if not read_byte:
# EOF on macOS ends up here.
break
read_byte = read_byte.decode('utf-8') if IS_PY_3 else read_byte
has_value, read_byte = self._read_stdout_byte()
if not has_value:
continue
if not read_byte:
# EOF on macOS ends up here.
break
read_byte = read_byte.decode('utf-8') if IS_PY_3 else read_byte
debug(read_byte)
if self.no_pty:
self.buf += read_byte.replace('\n', '\r\n')
else:
self.buf += read_byte
self.buf = self.buf.replace('\r\r', '\r')
debug(read_byte)
if self.no_pty:
self.buf += read_byte.replace('\n', '\r\n')
else:
self.buf += read_byte
self.buf = self.buf.replace('\r\r', '\r')
# filter the prompts
for prompt in prompts:
pattern = re.compile(prompt)
match = pattern.search(self.buf)
if match:
end = match.end()
buf = self.buf[0:end-len(prompt)]
self.buf = self.buf[end:]
return buf
# filter the prompts
for prompt in prompts:
pattern = re.compile(prompt)
match = pattern.search(self.buf)
if match:
end = match.end()
buf = self.buf[0:end-len(prompt)]
self.buf = self.buf[end:]
return buf
return None
def writeline(self, str):
@ -140,6 +192,8 @@ class Runner():
self.stdin.write(str_to_write)
def cleanup(self):
atexit.unregister(self.cleanup)
if self.process:
try:
self.writeline("__exit__")
@ -157,6 +211,8 @@ class Runner():
self.stdout = None
if not IS_PY_3:
sys.exc_clear()
if self._stream_reader:
self._stream_reader.cleanup()
def assert_prompt(runner, prompts, timeout, is_need_execute_result):
# Wait for the initial prompt
@ -402,9 +458,9 @@ def cast_v128_to_i64x2(numbers, type, lane_type):
unpacked = struct.unpack("Q Q", packed)
return unpacked, f"[{unpacked[0]:#x} {unpacked[1]:#x}]:{lane_type}:v128"
def parse_simple_const_w_type(number, type):
number = number.replace('_', '')
number = re.sub(r"nan\((ind|snan)\)", "nan", number)
if type in ["i32", "i64"]:
number = int(number, 16) if '0x' in number else int(number)
return number, "0x{:x}:{}".format(number, type) \
@ -941,7 +997,8 @@ def skip_test(form, skip_list):
def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts):
log("Writing WAST module to '%s'" % wast_tempfile)
open(wast_tempfile, 'w').write(form)
with open(wast_tempfile, 'w') as file:
file.write(form)
log("Compiling WASM to '%s'" % wasm_tempfile)
# default arguments
@ -1063,13 +1120,10 @@ def run_wasm_with_repl(wasm_tempfile, aot_tempfile, opts, r):
def create_tmpfiles(wast_name):
tempfiles = []
(t1fd, wast_tempfile) = tempfile.mkstemp(suffix=".wast")
(t2fd, wasm_tempfile) = tempfile.mkstemp(suffix=".wasm")
tempfiles.append(wast_tempfile)
tempfiles.append(wasm_tempfile)
tempfiles.append(create_tmp_file(".wast"))
tempfiles.append(create_tmp_file(".wasm"))
if test_aot:
(t3fd, aot_tempfile) = tempfile.mkstemp(suffix=".aot")
tempfiles.append(aot_tempfile)
tempfiles.append(create_tmp_file(".aot"))
# add these temp file to temporal repo, will be deleted when finishing the test
temp_file_repo.extend(tempfiles)
@ -1138,10 +1192,10 @@ if __name__ == "__main__":
else:
SKIP_TESTS = C_SKIP_TESTS
(t1fd, wast_tempfile) = tempfile.mkstemp(suffix=".wast")
(t2fd, wasm_tempfile) = tempfile.mkstemp(suffix=".wasm")
wast_tempfile = create_tmp_file(".wast")
wasm_tempfile = create_tmp_file(".wasm")
if test_aot:
(t3fd, aot_tempfile) = tempfile.mkstemp(suffix=".aot")
aot_tempfile = create_tmp_file(".aot")
ret_code = 0
try:
@ -1172,17 +1226,16 @@ if __name__ == "__main__":
# workaround: spec test changes error message to "malformed" while iwasm still use "invalid"
error_msg = m.group(2).replace("malformed", "invalid")
log("Testing(malformed)")
f = open(wasm_tempfile, 'wb')
s = m.group(1)
while s:
res = re.match("[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL)
if IS_PY_3:
context = res.group(1).replace("\\", "\\x").encode("latin1").decode("unicode-escape").encode("latin1")
f.write(context)
else:
f.write(res.group(1).replace("\\", "\\x").decode("string-escape"))
s = res.group(2)
f.close()
with open(wasm_tempfile, 'wb') as f:
s = m.group(1)
while s:
res = re.match("[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL)
if IS_PY_3:
context = res.group(1).replace("\\", "\\x").encode("latin1").decode("unicode-escape").encode("latin1")
f.write(context)
else:
f.write(res.group(1).replace("\\", "\\x").decode("string-escape"))
s = res.group(2)
# compile wasm to aot
if test_aot:

View File

@ -53,7 +53,13 @@ ENABLE_GC_HEAP_VERIFY=0
#unit test case arrary
TEST_CASE_ARR=()
SGX_OPT=""
PLATFORM=$(uname -s | tr A-Z a-z)
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
PLATFORM=windows
PYTHON_EXE=python
else
PLATFORM=$(uname -s | tr A-Z a-z)
PYTHON_EXE=python3
fi
PARALLELISM=0
ENABLE_QEMU=0
QEMU_FIRMWARE=""
@ -330,15 +336,18 @@ function setup_wabt()
darwin)
WABT_PLATFORM=macos
;;
windows)
WABT_PLATFORM=windows
;;
*)
echo "wabt platform for ${PLATFORM} in unknown"
exit 1
;;
esac
if [ ! -f /tmp/wabt-1.0.31-${WABT_PLATFORM}.tar.gz ]; then
wget \
curl -L \
https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-${WABT_PLATFORM}.tar.gz \
-P /tmp
-o /tmp/wabt-1.0.31-${WABT_PLATFORM}.tar.gz
fi
cd /tmp \
@ -493,12 +502,16 @@ function spec_test()
ARGS_FOR_SPEC_TEST+="--qemu-firmware ${QEMU_FIRMWARE} "
fi
if [[ ${PLATFORM} == "windows" ]]; then
ARGS_FOR_SPEC_TEST+="--no-pty "
fi
# set log directory
ARGS_FOR_SPEC_TEST+="--log ${REPORT_DIR}"
cd ${WORK_DIR}
echo "python3 ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/spec_test_report.txt"
python3 ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/spec_test_report.txt
echo "${PYTHON_EXE} ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/spec_test_report.txt"
${PYTHON_EXE} ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/spec_test_report.txt
if [[ ${PIPESTATUS[0]} -ne 0 ]];then
echo -e "\nspec tests FAILED" | tee -a ${REPORT_DIR}/spec_test_report.txt
exit 1
@ -559,7 +572,7 @@ function wasi_certification_test()
cd wasi-testsuite
git reset --hard ${WASI_TESTSUITE_COMMIT}
TSAN_OPTIONS=${TSAN_OPTIONS} bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET \
TSAN_OPTIONS=${TSAN_OPTIONS} bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET $WASI_TEST_FILTER \
| tee -a ${REPORT_DIR}/wasi_test_report.txt
ret=${PIPESTATUS[0]}
@ -689,7 +702,7 @@ function build_iwasm_with_cfg()
&& if [ -d build ]; then rm -rf build/*; else mkdir build; fi \
&& cd build \
&& cmake $* .. \
&& make -j 4
&& cmake --build . -j 4 --config RelWithDebInfo
fi
if [ "$?" != 0 ];then
@ -829,6 +842,17 @@ function trigger()
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_SANITIZER=tsan"
fi
# Make sure we're using the builtin WASI libc implementation
# if we're running the wasi certification tests.
if [[ $TEST_CASE_ARR ]]; then
for test in "${TEST_CASE_ARR[@]}"; do
if [[ "$test" == "wasi_certification" ]]; then
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1"
break
fi
done
fi
for t in "${TYPE[@]}"; do
case $t in
"classic-interp")

View File

@ -9,11 +9,25 @@ THIS_DIR=$(cd $(dirname $0) && pwd -P)
readonly MODE=$1
readonly TARGET=$2
readonly TEST_FILTER=$3
readonly WORK_DIR=$PWD
readonly PLATFORM=$(uname -s | tr A-Z a-z)
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
readonly PLATFORM=windows
readonly PYTHON_EXE=python
# see https://github.com/pypa/virtualenv/commit/993ba1316a83b760370f5a3872b3f5ef4dd904c1
readonly VENV_BIN_DIR=Scripts
readonly IWASM_EXE=$(cygpath -m "${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/build/RelWithDebInfo/iwasm.exe")
else
readonly PLATFORM=$(uname -s | tr A-Z a-z)
readonly VENV_BIN_DIR=bin
readonly PYTHON_EXE=python3
readonly IWASM_EXE="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/build/iwasm"
fi
readonly WAMR_DIR="${WORK_DIR}/../../../.."
readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/build/iwasm \
readonly IWASM_CMD="${IWASM_EXE} \
--allow-resolve=google-public-dns-a.google.com \
--addr-pool=::1/128,127.0.0.1/32"
@ -28,8 +42,21 @@ readonly THREAD_STRESS_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/
readonly LIB_SOCKET_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/"
run_aot_tests () {
local tests=("$@")
local -n tests=$1
local -n excluded_tests=$2
for test_wasm in ${tests[@]}; do
# get the base file name from the filepath
local test_name=${test_wasm##*/}
test_name=${test_name%.wasm}
for excluded_test in "${excluded_tests[@]}"; do
if [[ $excluded_test == "\"$test_name\"" ]]; then
echo "Skipping test $test_name"
continue 2
fi
done
local iwasm="${IWASM_CMD}"
if [[ $test_wasm =~ "stress" ]]; then
iwasm="${IWASM_CMD_STRESS}"
@ -37,7 +64,7 @@ run_aot_tests () {
test_aot="${test_wasm%.wasm}.aot"
test_json="${test_wasm%.wasm}.json"
if [ -f ${test_wasm} ]; then
expected=$(jq .exit_code ${test_json})
fi
@ -52,7 +79,7 @@ run_aot_tests () {
expected=$(jq .exit_code ${test_json})
fi
python3 ${THIS_DIR}/pipe.py | ${iwasm} $test_aot
$PYTHON_EXE ${THIS_DIR}/pipe.py | ${iwasm} $test_aot
ret=${PIPESTATUS[1]}
echo "expected=$expected, actual=$ret"
@ -63,23 +90,29 @@ run_aot_tests () {
}
if [[ $MODE != "aot" ]];then
python3 -m venv wasi-env && source wasi-env/bin/activate
python3 -m pip install -r test-runner/requirements.txt
$PYTHON_EXE -m venv wasi-env && source wasi-env/${VENV_BIN_DIR}/activate
$PYTHON_EXE -m pip install -r test-runner/requirements.txt
export TEST_RUNTIME_EXE="${IWASM_CMD}"
python3 ${THIS_DIR}/pipe.py | TSAN_OPTIONS=${TSAN_OPTIONS} python3 test-runner/wasi_test_runner.py \
-r adapters/wasm-micro-runtime.py \
-t \
${C_TESTS} \
${RUST_TESTS} \
${ASSEMBLYSCRIPT_TESTS} \
${THREAD_PROPOSAL_TESTS} \
${THREAD_INTERNAL_TESTS} \
${LIB_SOCKET_TESTS} \
TEST_OPTIONS="-r adapters/wasm-micro-runtime.py \
-t \
${C_TESTS} \
${RUST_TESTS} \
${ASSEMBLYSCRIPT_TESTS} \
${THREAD_PROPOSAL_TESTS} \
${THREAD_INTERNAL_TESTS} \
${LIB_SOCKET_TESTS}"
if [ -n "$TEST_FILTER" ]; then
TEST_OPTIONS="${TEST_OPTIONS} --exclude-filter ${TEST_FILTER}"
fi
$PYTHON_EXE ${THIS_DIR}/pipe.py | TSAN_OPTIONS=${TSAN_OPTIONS} $PYTHON_EXE test-runner/wasi_test_runner.py $TEST_OPTIONS
ret=${PIPESTATUS[1]}
TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" TSAN_OPTIONS=${TSAN_OPTIONS} python3 test-runner/wasi_test_runner.py \
TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" TSAN_OPTIONS=${TSAN_OPTIONS} $PYTHON_EXE test-runner/wasi_test_runner.py \
-r adapters/wasm-micro-runtime.py \
-t \
${THREAD_STRESS_TESTS}
@ -87,9 +120,9 @@ if [[ $MODE != "aot" ]];then
if [ "${ret}" -eq 0 ]; then
ret=${PIPESTATUS[0]}
fi
exit_code=${ret}
deactivate
else
target_option=""
@ -101,7 +134,17 @@ else
for testsuite in ${THREAD_STRESS_TESTS} ${THREAD_PROPOSAL_TESTS} ${THREAD_INTERNAL_TESTS}; do
tests=$(ls ${testsuite}*.wasm)
tests_array=($tests)
run_aot_tests "${tests_array[@]}"
if [ -n "$TEST_FILTER" ]; then
readarray -t excluded_tests_array < <(jq -c \
--slurpfile testsuite_manifest $testsuite/manifest.json \
'.[$testsuite_manifest[0].name] // {} | keys[]' \
$TEST_FILTER)
else
excluded_tests_array=()
fi
run_aot_tests tests_array excluded_tests_array
done
fi

View File

@ -198,6 +198,12 @@ include_directories (${SHARED_DIR}/include
enable_language (ASM)
if (NOT MINGW AND NOT MSVC)
set(WAMR_BUILD_LIBC_WASI 1)
else()
set(WAMR_BUILD_LIBC_UVWASI 1)
endif()
include (${SHARED_DIR}/platform/${WAMR_BUILD_PLATFORM}/shared_platform.cmake)
include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake)
include (${SHARED_DIR}/utils/shared_utils.cmake)