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:
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
256
core/shared/platform/common/libc-util/libc_errno.c
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "errno.h"
|
||||
#include "libc_errno.h"
|
||||
|
||||
__wasi_errno_t
|
||||
convert_errno(int error)
|
||||
{
|
||||
// The C standard library only requires EDOM, EILSEQ and ERANGE to be
|
||||
// defined. Other error codes are POSIX-specific and hence may or may
|
||||
// not be available on non-POSIX platforms.
|
||||
__wasi_errno_t code = __WASI_ENOSYS;
|
||||
#define X(v) \
|
||||
case v: \
|
||||
code = __WASI_##v; \
|
||||
break;
|
||||
switch (error) {
|
||||
X(EDOM)
|
||||
X(EILSEQ)
|
||||
X(ERANGE)
|
||||
#ifdef E2BIG
|
||||
X(E2BIG)
|
||||
#endif
|
||||
#ifdef EACCES
|
||||
X(EACCES)
|
||||
#endif
|
||||
#ifdef EADDRINUSE
|
||||
X(EADDRINUSE)
|
||||
#endif
|
||||
#ifdef EADDRNOTAVAIL
|
||||
X(EADDRNOTAVAIL)
|
||||
#endif
|
||||
#ifdef EAFNOSUPPORT
|
||||
X(EAFNOSUPPORT)
|
||||
#endif
|
||||
#ifdef EAGAIN
|
||||
X(EAGAIN)
|
||||
#endif
|
||||
#ifdef EALREADY
|
||||
X(EALREADY)
|
||||
#endif
|
||||
#ifdef EBADF
|
||||
X(EBADF)
|
||||
#endif
|
||||
#ifdef EBADMSG
|
||||
X(EBADMSG)
|
||||
#endif
|
||||
#ifdef EBUSY
|
||||
X(EBUSY)
|
||||
#endif
|
||||
#ifdef ECANCELED
|
||||
X(ECANCELED)
|
||||
#endif
|
||||
#ifdef ECHILD
|
||||
X(ECHILD)
|
||||
#endif
|
||||
#ifdef ECONNABORTED
|
||||
X(ECONNABORTED)
|
||||
#endif
|
||||
#ifdef ECONNREFUSED
|
||||
X(ECONNREFUSED)
|
||||
#endif
|
||||
#ifdef ECONNRESET
|
||||
X(ECONNRESET)
|
||||
#endif
|
||||
#ifdef EDEADLK
|
||||
X(EDEADLK)
|
||||
#endif
|
||||
#ifdef EDESTADDRREQ
|
||||
X(EDESTADDRREQ)
|
||||
#endif
|
||||
#ifdef EDQUOT
|
||||
X(EDQUOT)
|
||||
#endif
|
||||
#ifdef EEXIST
|
||||
X(EEXIST)
|
||||
#endif
|
||||
#ifdef EFAULT
|
||||
X(EFAULT)
|
||||
#endif
|
||||
#ifdef EFBIG
|
||||
X(EFBIG)
|
||||
#endif
|
||||
#ifdef EHOSTUNREACH
|
||||
X(EHOSTUNREACH)
|
||||
#endif
|
||||
#ifdef EIDRM
|
||||
X(EIDRM)
|
||||
#endif
|
||||
#ifdef EINPROGRESS
|
||||
X(EINPROGRESS)
|
||||
#endif
|
||||
#ifdef EINTR
|
||||
X(EINTR)
|
||||
#endif
|
||||
#ifdef EINVAL
|
||||
X(EINVAL)
|
||||
#endif
|
||||
#ifdef EIO
|
||||
X(EIO)
|
||||
#endif
|
||||
#ifdef EISCONN
|
||||
X(EISCONN)
|
||||
#endif
|
||||
#ifdef EISDIR
|
||||
X(EISDIR)
|
||||
#endif
|
||||
#ifdef ELOOP
|
||||
X(ELOOP)
|
||||
#endif
|
||||
#ifdef EMFILE
|
||||
X(EMFILE)
|
||||
#endif
|
||||
#ifdef EMLINK
|
||||
X(EMLINK)
|
||||
#endif
|
||||
#ifdef EMSGSIZE
|
||||
X(EMSGSIZE)
|
||||
#endif
|
||||
#ifdef EMULTIHOP
|
||||
X(EMULTIHOP)
|
||||
#endif
|
||||
#ifdef ENAMETOOLONG
|
||||
X(ENAMETOOLONG)
|
||||
#endif
|
||||
#ifdef ENETDOWN
|
||||
X(ENETDOWN)
|
||||
#endif
|
||||
#ifdef ENETRESET
|
||||
X(ENETRESET)
|
||||
#endif
|
||||
#ifdef ENETUNREACH
|
||||
X(ENETUNREACH)
|
||||
#endif
|
||||
#ifdef ENFILE
|
||||
X(ENFILE)
|
||||
#endif
|
||||
#ifdef ENOBUFS
|
||||
X(ENOBUFS)
|
||||
#endif
|
||||
#ifdef ENODEV
|
||||
X(ENODEV)
|
||||
#endif
|
||||
#ifdef ENOENT
|
||||
X(ENOENT)
|
||||
#endif
|
||||
#ifdef ENOEXEC
|
||||
X(ENOEXEC)
|
||||
#endif
|
||||
#ifdef ENOLCK
|
||||
X(ENOLCK)
|
||||
#endif
|
||||
#ifdef ENOLINK
|
||||
X(ENOLINK)
|
||||
#endif
|
||||
#ifdef ENOMEM
|
||||
X(ENOMEM)
|
||||
#endif
|
||||
#ifdef ENOMSG
|
||||
X(ENOMSG)
|
||||
#endif
|
||||
#ifdef ENOPROTOOPT
|
||||
X(ENOPROTOOPT)
|
||||
#endif
|
||||
#ifdef ENOSPC
|
||||
X(ENOSPC)
|
||||
#endif
|
||||
#ifdef ENOSYS
|
||||
X(ENOSYS)
|
||||
#endif
|
||||
#ifdef ENOTCAPABLE
|
||||
X(ENOTCAPABLE)
|
||||
#endif
|
||||
#ifdef ENOTCONN
|
||||
X(ENOTCONN)
|
||||
#endif
|
||||
#ifdef ENOTDIR
|
||||
X(ENOTDIR)
|
||||
#endif
|
||||
#ifdef ENOTEMPTY
|
||||
X(ENOTEMPTY)
|
||||
#endif
|
||||
#ifdef ENOTRECOVERABLE
|
||||
X(ENOTRECOVERABLE)
|
||||
#endif
|
||||
#ifdef ENOTSOCK
|
||||
X(ENOTSOCK)
|
||||
#endif
|
||||
#ifdef ENOTSUP
|
||||
X(ENOTSUP)
|
||||
#endif
|
||||
#ifdef ENOTTY
|
||||
X(ENOTTY)
|
||||
#endif
|
||||
#ifdef ENXIO
|
||||
X(ENXIO)
|
||||
#endif
|
||||
#ifdef EOVERFLOW
|
||||
X(EOVERFLOW)
|
||||
#endif
|
||||
#ifdef EOWNERDEAD
|
||||
X(EOWNERDEAD)
|
||||
#endif
|
||||
#ifdef EPERM
|
||||
X(EPERM)
|
||||
#endif
|
||||
#ifdef EPIPE
|
||||
X(EPIPE)
|
||||
#endif
|
||||
#ifdef EPROTO
|
||||
X(EPROTO)
|
||||
#endif
|
||||
#ifdef EPROTONOSUPPORT
|
||||
X(EPROTONOSUPPORT)
|
||||
#endif
|
||||
#ifdef EPROTOTYPE
|
||||
X(EPROTOTYPE)
|
||||
#endif
|
||||
#ifdef EROFS
|
||||
X(EROFS)
|
||||
#endif
|
||||
#ifdef ESPIPE
|
||||
X(ESPIPE)
|
||||
#endif
|
||||
#ifdef ESRCH
|
||||
X(ESRCH)
|
||||
#endif
|
||||
#ifdef ESTALE
|
||||
X(ESTALE)
|
||||
#endif
|
||||
#ifdef ETIMEDOUT
|
||||
X(ETIMEDOUT)
|
||||
#endif
|
||||
#ifdef ETXTBSY
|
||||
X(ETXTBSY)
|
||||
#endif
|
||||
#ifdef EXDEV
|
||||
X(EXDEV)
|
||||
#endif
|
||||
default:
|
||||
#ifdef EOPNOTSUPP
|
||||
if (error == EOPNOTSUPP)
|
||||
code = __WASI_ENOTSUP;
|
||||
#endif
|
||||
#ifdef EWOULDBLOCK
|
||||
if (error == EWOULDBLOCK)
|
||||
code = __WASI_EAGAIN;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#undef X
|
||||
return code;
|
||||
}
|
||||
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
15
core/shared/platform/common/libc-util/libc_errno.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef WASI_ERRNO_H
|
||||
#define WASI_ERRNO_H
|
||||
|
||||
#include "platform_wasi_types.h"
|
||||
|
||||
// Converts an errno error code to a WASI error code.
|
||||
__wasi_errno_t
|
||||
convert_errno(int error);
|
||||
|
||||
#endif /* end of WASI_ERRNO_H */
|
||||
@ -0,0 +1,8 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (PLATFORM_COMMON_LIBC_UTIL_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${PLATFORM_COMMON_LIBC_UTIL_DIR})
|
||||
|
||||
file (GLOB_RECURSE PLATFORM_COMMON_LIBC_UTIL_SOURCE ${PLATFORM_COMMON_LIBC_UTIL_DIR}/*.c)
|
||||
@ -5,4 +5,14 @@ set (PLATFORM_COMMON_POSIX_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_COMMON_POSIX_DIR}/*.c)
|
||||
|
||||
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} )
|
||||
|
||||
86
core/shared/platform/common/posix/posix_clock.c
Normal file
86
core/shared/platform/common/posix/posix_clock.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "libc_errno.h"
|
||||
#include "platform_api_extension.h"
|
||||
|
||||
#define NANOSECONDS_PER_SECOND 1000000000ULL
|
||||
|
||||
static __wasi_errno_t
|
||||
wasi_clockid_to_clockid(__wasi_clockid_t in, clockid_t *out)
|
||||
{
|
||||
switch (in) {
|
||||
case __WASI_CLOCK_MONOTONIC:
|
||||
*out = CLOCK_MONOTONIC;
|
||||
return __WASI_ESUCCESS;
|
||||
case __WASI_CLOCK_REALTIME:
|
||||
*out = CLOCK_REALTIME;
|
||||
return __WASI_ESUCCESS;
|
||||
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||
#if defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||
*out = CLOCK_PROCESS_CPUTIME_ID;
|
||||
return __WASI_ESUCCESS;
|
||||
#else
|
||||
return __WASI_ENOTSUP;
|
||||
#endif
|
||||
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||
#if defined(CLOCK_THREAD_CPUTIME_ID)
|
||||
*out = CLOCK_THREAD_CPUTIME_ID;
|
||||
return __WASI_ESUCCESS;
|
||||
#else
|
||||
return __WASI_ENOTSUP;
|
||||
#endif
|
||||
default:
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static __wasi_timestamp_t
|
||||
timespec_to_nanoseconds(const struct timespec *ts)
|
||||
{
|
||||
if (ts->tv_sec < 0)
|
||||
return 0;
|
||||
if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / NANOSECONDS_PER_SECOND)
|
||||
return UINT64_MAX;
|
||||
return (__wasi_timestamp_t)ts->tv_sec * NANOSECONDS_PER_SECOND
|
||||
+ (__wasi_timestamp_t)ts->tv_nsec;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
|
||||
{
|
||||
clockid_t nclock_id;
|
||||
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
struct timespec ts;
|
||||
if (clock_getres(nclock_id, &ts) < 0)
|
||||
return convert_errno(errno);
|
||||
|
||||
*resolution = timespec_to_nanoseconds(&ts);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||
__wasi_timestamp_t *time)
|
||||
{
|
||||
clockid_t nclock_id;
|
||||
__wasi_errno_t error = wasi_clockid_to_clockid(clock_id, &nclock_id);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
struct timespec ts;
|
||||
if (clock_gettime(nclock_id, &ts) < 0)
|
||||
return convert_errno(errno);
|
||||
|
||||
*time = timespec_to_nanoseconds(&ts);
|
||||
|
||||
return error;
|
||||
}
|
||||
1013
core/shared/platform/common/posix/posix_file.c
Normal file
1013
core/shared/platform/common/posix/posix_file.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
{
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -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
|
||||
|
||||
610
core/shared/platform/include/platform_wasi_types.h
Normal file
610
core/shared/platform/include/platform_wasi_types.h
Normal file
@ -0,0 +1,610 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file declares the WASI interface. The definitions of types, macros and
|
||||
* structures in this file should be consistent with those in wasi-libc:
|
||||
* https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/headers/public/wasi/api.h
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_WASI_TYPES_H
|
||||
#define _PLATFORM_WASI_TYPES_H
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef _Static_assert
|
||||
#define _Static_assert static_assert
|
||||
#endif /* _Static_assert */
|
||||
|
||||
#ifndef _Alignof
|
||||
#define _Alignof alignof
|
||||
#endif /* _Alignof */
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* There is no need to check the WASI layout if we're using uvwasi or libc-wasi
|
||||
* is not enabled at all. */
|
||||
#if WASM_ENABLE_UVWASI != 0 || WASM_ENABLE_LIBC_WASI == 0
|
||||
#define assert_wasi_layout(expr, message) /* nothing */
|
||||
#else
|
||||
#define assert_wasi_layout(expr, message) _Static_assert(expr, message)
|
||||
#endif
|
||||
|
||||
assert_wasi_layout(_Alignof(int8_t) == 1, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(uint8_t) == 1, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(int16_t) == 2, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(uint16_t) == 2, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(int32_t) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(uint32_t) == 4, "non-wasi data layout");
|
||||
#if 0
|
||||
assert_wasi_layout(_Alignof(int64_t) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(uint64_t) == 8, "non-wasi data layout");
|
||||
#endif
|
||||
|
||||
typedef uint32_t __wasi_size_t;
|
||||
assert_wasi_layout(_Alignof(__wasi_size_t) == 4, "non-wasi data layout");
|
||||
|
||||
typedef uint8_t __wasi_advice_t;
|
||||
#define __WASI_ADVICE_NORMAL (0)
|
||||
#define __WASI_ADVICE_SEQUENTIAL (1)
|
||||
#define __WASI_ADVICE_RANDOM (2)
|
||||
#define __WASI_ADVICE_WILLNEED (3)
|
||||
#define __WASI_ADVICE_DONTNEED (4)
|
||||
#define __WASI_ADVICE_NOREUSE (5)
|
||||
|
||||
typedef uint32_t __wasi_clockid_t;
|
||||
#define __WASI_CLOCK_REALTIME (0)
|
||||
#define __WASI_CLOCK_MONOTONIC (1)
|
||||
#define __WASI_CLOCK_PROCESS_CPUTIME_ID (2)
|
||||
#define __WASI_CLOCK_THREAD_CPUTIME_ID (3)
|
||||
|
||||
typedef uint64_t __wasi_device_t;
|
||||
|
||||
typedef uint64_t __wasi_dircookie_t;
|
||||
#define __WASI_DIRCOOKIE_START (0)
|
||||
|
||||
typedef uint32_t __wasi_dirnamlen_t;
|
||||
|
||||
typedef uint16_t __wasi_errno_t;
|
||||
#define __WASI_ESUCCESS (0)
|
||||
#define __WASI_E2BIG (1)
|
||||
#define __WASI_EACCES (2)
|
||||
#define __WASI_EADDRINUSE (3)
|
||||
#define __WASI_EADDRNOTAVAIL (4)
|
||||
#define __WASI_EAFNOSUPPORT (5)
|
||||
#define __WASI_EAGAIN (6)
|
||||
#define __WASI_EALREADY (7)
|
||||
#define __WASI_EBADF (8)
|
||||
#define __WASI_EBADMSG (9)
|
||||
#define __WASI_EBUSY (10)
|
||||
#define __WASI_ECANCELED (11)
|
||||
#define __WASI_ECHILD (12)
|
||||
#define __WASI_ECONNABORTED (13)
|
||||
#define __WASI_ECONNREFUSED (14)
|
||||
#define __WASI_ECONNRESET (15)
|
||||
#define __WASI_EDEADLK (16)
|
||||
#define __WASI_EDESTADDRREQ (17)
|
||||
#define __WASI_EDOM (18)
|
||||
#define __WASI_EDQUOT (19)
|
||||
#define __WASI_EEXIST (20)
|
||||
#define __WASI_EFAULT (21)
|
||||
#define __WASI_EFBIG (22)
|
||||
#define __WASI_EHOSTUNREACH (23)
|
||||
#define __WASI_EIDRM (24)
|
||||
#define __WASI_EILSEQ (25)
|
||||
#define __WASI_EINPROGRESS (26)
|
||||
#define __WASI_EINTR (27)
|
||||
#define __WASI_EINVAL (28)
|
||||
#define __WASI_EIO (29)
|
||||
#define __WASI_EISCONN (30)
|
||||
#define __WASI_EISDIR (31)
|
||||
#define __WASI_ELOOP (32)
|
||||
#define __WASI_EMFILE (33)
|
||||
#define __WASI_EMLINK (34)
|
||||
#define __WASI_EMSGSIZE (35)
|
||||
#define __WASI_EMULTIHOP (36)
|
||||
#define __WASI_ENAMETOOLONG (37)
|
||||
#define __WASI_ENETDOWN (38)
|
||||
#define __WASI_ENETRESET (39)
|
||||
#define __WASI_ENETUNREACH (40)
|
||||
#define __WASI_ENFILE (41)
|
||||
#define __WASI_ENOBUFS (42)
|
||||
#define __WASI_ENODEV (43)
|
||||
#define __WASI_ENOENT (44)
|
||||
#define __WASI_ENOEXEC (45)
|
||||
#define __WASI_ENOLCK (46)
|
||||
#define __WASI_ENOLINK (47)
|
||||
#define __WASI_ENOMEM (48)
|
||||
#define __WASI_ENOMSG (49)
|
||||
#define __WASI_ENOPROTOOPT (50)
|
||||
#define __WASI_ENOSPC (51)
|
||||
#define __WASI_ENOSYS (52)
|
||||
#define __WASI_ENOTCONN (53)
|
||||
#define __WASI_ENOTDIR (54)
|
||||
#define __WASI_ENOTEMPTY (55)
|
||||
#define __WASI_ENOTRECOVERABLE (56)
|
||||
#define __WASI_ENOTSOCK (57)
|
||||
#define __WASI_ENOTSUP (58)
|
||||
#define __WASI_ENOTTY (59)
|
||||
#define __WASI_ENXIO (60)
|
||||
#define __WASI_EOVERFLOW (61)
|
||||
#define __WASI_EOWNERDEAD (62)
|
||||
#define __WASI_EPERM (63)
|
||||
#define __WASI_EPIPE (64)
|
||||
#define __WASI_EPROTO (65)
|
||||
#define __WASI_EPROTONOSUPPORT (66)
|
||||
#define __WASI_EPROTOTYPE (67)
|
||||
#define __WASI_ERANGE (68)
|
||||
#define __WASI_EROFS (69)
|
||||
#define __WASI_ESPIPE (70)
|
||||
#define __WASI_ESRCH (71)
|
||||
#define __WASI_ESTALE (72)
|
||||
#define __WASI_ETIMEDOUT (73)
|
||||
#define __WASI_ETXTBSY (74)
|
||||
#define __WASI_EXDEV (75)
|
||||
#define __WASI_ENOTCAPABLE (76)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGNED_(x) __declspec(align(x))
|
||||
#define WARN_UNUSED _Check_return_
|
||||
#elif defined(__GNUC__)
|
||||
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||
#define WARN_UNUSED __attribute__((__warn_unused_result__))
|
||||
#endif
|
||||
|
||||
#define ALIGNED_TYPE(t,x) typedef t ALIGNED_(x)
|
||||
|
||||
typedef uint16_t __wasi_eventrwflags_t;
|
||||
#define __WASI_EVENT_FD_READWRITE_HANGUP (0x0001)
|
||||
|
||||
typedef uint8_t __wasi_eventtype_t;
|
||||
#define __WASI_EVENTTYPE_CLOCK (0)
|
||||
#define __WASI_EVENTTYPE_FD_READ (1)
|
||||
#define __WASI_EVENTTYPE_FD_WRITE (2)
|
||||
|
||||
typedef uint32_t __wasi_exitcode_t;
|
||||
|
||||
typedef uint32_t __wasi_fd_t;
|
||||
|
||||
typedef uint16_t __wasi_fdflags_t;
|
||||
#define __WASI_FDFLAG_APPEND (0x0001)
|
||||
#define __WASI_FDFLAG_DSYNC (0x0002)
|
||||
#define __WASI_FDFLAG_NONBLOCK (0x0004)
|
||||
#define __WASI_FDFLAG_RSYNC (0x0008)
|
||||
#define __WASI_FDFLAG_SYNC (0x0010)
|
||||
|
||||
typedef int64_t __wasi_filedelta_t;
|
||||
|
||||
typedef uint64_t __wasi_filesize_t;
|
||||
|
||||
typedef uint8_t __wasi_filetype_t;
|
||||
#define __WASI_FILETYPE_UNKNOWN (0)
|
||||
#define __WASI_FILETYPE_BLOCK_DEVICE (1)
|
||||
#define __WASI_FILETYPE_CHARACTER_DEVICE (2)
|
||||
#define __WASI_FILETYPE_DIRECTORY (3)
|
||||
#define __WASI_FILETYPE_REGULAR_FILE (4)
|
||||
#define __WASI_FILETYPE_SOCKET_DGRAM (5)
|
||||
#define __WASI_FILETYPE_SOCKET_STREAM (6)
|
||||
#define __WASI_FILETYPE_SYMBOLIC_LINK (7)
|
||||
|
||||
typedef uint16_t __wasi_fstflags_t;
|
||||
#define __WASI_FILESTAT_SET_ATIM (0x0001)
|
||||
#define __WASI_FILESTAT_SET_ATIM_NOW (0x0002)
|
||||
#define __WASI_FILESTAT_SET_MTIM (0x0004)
|
||||
#define __WASI_FILESTAT_SET_MTIM_NOW (0x0008)
|
||||
|
||||
typedef uint64_t __wasi_inode_t;
|
||||
|
||||
ALIGNED_TYPE(uint64_t, 8) __wasi_linkcount_t;
|
||||
|
||||
typedef uint32_t __wasi_lookupflags_t;
|
||||
#define __WASI_LOOKUP_SYMLINK_FOLLOW (0x00000001)
|
||||
|
||||
typedef uint16_t __wasi_oflags_t;
|
||||
#define __WASI_O_CREAT (0x0001)
|
||||
#define __WASI_O_DIRECTORY (0x0002)
|
||||
#define __WASI_O_EXCL (0x0004)
|
||||
#define __WASI_O_TRUNC (0x0008)
|
||||
|
||||
typedef uint16_t __wasi_riflags_t;
|
||||
#define __WASI_SOCK_RECV_PEEK (0x0001)
|
||||
#define __WASI_SOCK_RECV_WAITALL (0x0002)
|
||||
|
||||
typedef uint64_t __wasi_rights_t;
|
||||
|
||||
/**
|
||||
* Observe that WASI defines rights in the plural form
|
||||
* TODO: refactor to use RIGHTS instead of RIGHT
|
||||
*/
|
||||
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(UINT64_C(1) << 0))
|
||||
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(UINT64_C(1) << 1))
|
||||
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(UINT64_C(1) << 2))
|
||||
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(UINT64_C(1) << 3))
|
||||
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(UINT64_C(1) << 4))
|
||||
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(UINT64_C(1) << 5))
|
||||
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(UINT64_C(1) << 6))
|
||||
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(UINT64_C(1) << 7))
|
||||
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(UINT64_C(1) << 8))
|
||||
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 9))
|
||||
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(UINT64_C(1) << 10))
|
||||
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 11))
|
||||
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(UINT64_C(1) << 12))
|
||||
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(UINT64_C(1) << 13))
|
||||
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(UINT64_C(1) << 14))
|
||||
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(UINT64_C(1) << 15))
|
||||
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 16))
|
||||
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(UINT64_C(1) << 17))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 18))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 19))
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 20))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 21))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 22))
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 23))
|
||||
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(UINT64_C(1) << 24))
|
||||
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 25))
|
||||
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(UINT64_C(1) << 26))
|
||||
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(UINT64_C(1) << 27))
|
||||
#define __WASI_RIGHT_SOCK_CONNECT ((__wasi_rights_t)(UINT64_C(1) << 28))
|
||||
#define __WASI_RIGHT_SOCK_LISTEN ((__wasi_rights_t)(UINT64_C(1) << 29))
|
||||
#define __WASI_RIGHT_SOCK_BIND ((__wasi_rights_t)(UINT64_C(1) << 30))
|
||||
#define __WASI_RIGHT_SOCK_ACCEPT ((__wasi_rights_t)(UINT64_C(1) << 31))
|
||||
#define __WASI_RIGHT_SOCK_RECV ((__wasi_rights_t)(UINT64_C(1) << 32))
|
||||
#define __WASI_RIGHT_SOCK_SEND ((__wasi_rights_t)(UINT64_C(1) << 33))
|
||||
#define __WASI_RIGHT_SOCK_ADDR_LOCAL ((__wasi_rights_t)(UINT64_C(1) << 34))
|
||||
#define __WASI_RIGHT_SOCK_ADDR_REMOTE ((__wasi_rights_t)(UINT64_C(1) << 35))
|
||||
#define __WASI_RIGHT_SOCK_RECV_FROM ((__wasi_rights_t)(UINT64_C(1) << 36))
|
||||
#define __WASI_RIGHT_SOCK_SEND_TO ((__wasi_rights_t)(UINT64_C(1) << 37))
|
||||
|
||||
typedef uint16_t __wasi_roflags_t;
|
||||
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
|
||||
|
||||
typedef uint8_t __wasi_sdflags_t;
|
||||
#define __WASI_SHUT_RD (0x01)
|
||||
#define __WASI_SHUT_WR (0x02)
|
||||
|
||||
typedef uint16_t __wasi_siflags_t;
|
||||
|
||||
typedef uint8_t __wasi_signal_t;
|
||||
|
||||
typedef uint16_t __wasi_subclockflags_t;
|
||||
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
|
||||
|
||||
typedef uint64_t __wasi_timestamp_t;
|
||||
|
||||
typedef uint64_t __wasi_userdata_t;
|
||||
|
||||
typedef uint8_t __wasi_whence_t;
|
||||
#define __WASI_WHENCE_SET (0)
|
||||
#define __WASI_WHENCE_CUR (1)
|
||||
#define __WASI_WHENCE_END (2)
|
||||
|
||||
typedef uint8_t __wasi_preopentype_t;
|
||||
#define __WASI_PREOPENTYPE_DIR (0)
|
||||
|
||||
struct fd_table;
|
||||
struct fd_prestats;
|
||||
struct argv_environ_values;
|
||||
struct addr_pool;
|
||||
|
||||
typedef struct ALIGNED_(8) __wasi_dirent_t {
|
||||
__wasi_dircookie_t d_next;
|
||||
__wasi_inode_t d_ino;
|
||||
__wasi_dirnamlen_t d_namlen;
|
||||
__wasi_filetype_t d_type;
|
||||
} __wasi_dirent_t;
|
||||
assert_wasi_layout(offsetof(__wasi_dirent_t, d_next) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_dirent_t, d_ino) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_dirent_t, d_namlen) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_dirent_t, d_type) == 20, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(__wasi_dirent_t) == 24, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(__wasi_dirent_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct ALIGNED_(8) __wasi_event_t {
|
||||
__wasi_userdata_t userdata;
|
||||
__wasi_errno_t error;
|
||||
__wasi_eventtype_t type;
|
||||
uint8_t __paddings[5];
|
||||
union __wasi_event_u {
|
||||
struct __wasi_event_u_fd_readwrite_t {
|
||||
__wasi_filesize_t nbytes;
|
||||
__wasi_eventrwflags_t flags;
|
||||
uint8_t __paddings[6];
|
||||
} fd_readwrite;
|
||||
} u;
|
||||
} __wasi_event_t;
|
||||
assert_wasi_layout(offsetof(__wasi_event_t, userdata) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_event_t, error) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_event_t, type) == 10, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_event_t, u.fd_readwrite.nbytes) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_event_t, u.fd_readwrite.flags) == 24, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(__wasi_event_t) == 32, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(__wasi_event_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_prestat_t {
|
||||
__wasi_preopentype_t pr_type;
|
||||
union __wasi_prestat_u {
|
||||
struct __wasi_prestat_u_dir_t {
|
||||
size_t pr_name_len;
|
||||
} dir;
|
||||
} u;
|
||||
} __wasi_prestat_t;
|
||||
assert_wasi_layout(offsetof(__wasi_prestat_t, pr_type) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_prestat_t) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_prestat_t) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct ALIGNED_(8) __wasi_fdstat_t {
|
||||
__wasi_filetype_t fs_filetype;
|
||||
__wasi_fdflags_t fs_flags;
|
||||
uint8_t __paddings[4];
|
||||
__wasi_rights_t fs_rights_base;
|
||||
__wasi_rights_t fs_rights_inheriting;
|
||||
} __wasi_fdstat_t;
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_fdstat_t, fs_filetype) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_fdstat_t, fs_flags) == 2, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_fdstat_t, fs_rights_base) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_fdstat_t, fs_rights_inheriting) == 16,
|
||||
"non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(__wasi_fdstat_t) == 24, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(__wasi_fdstat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct ALIGNED_(8) __wasi_filestat_t {
|
||||
__wasi_device_t st_dev;
|
||||
__wasi_inode_t st_ino;
|
||||
__wasi_filetype_t st_filetype;
|
||||
__wasi_linkcount_t st_nlink;
|
||||
__wasi_filesize_t st_size;
|
||||
__wasi_timestamp_t st_atim;
|
||||
__wasi_timestamp_t st_mtim;
|
||||
__wasi_timestamp_t st_ctim;
|
||||
} __wasi_filestat_t;
|
||||
assert_wasi_layout(offsetof(__wasi_filestat_t, st_dev) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(offsetof(__wasi_filestat_t, st_ino) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_filetype) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_nlink) == 24, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_size) == 32, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_atim) == 40, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_mtim) == 48, "non-wasi data layout");
|
||||
assert_wasi_layout(
|
||||
offsetof(__wasi_filestat_t, st_ctim) == 56, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(__wasi_filestat_t) == 64, "non-wasi data layout");
|
||||
assert_wasi_layout(_Alignof(__wasi_filestat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_ciovec_t {
|
||||
const void *buf;
|
||||
size_t buf_len;
|
||||
} __wasi_ciovec_t;
|
||||
assert_wasi_layout(offsetof(__wasi_ciovec_t, buf) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_ciovec_t, buf_len) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_ciovec_t, buf_len) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_ciovec_t) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_ciovec_t) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_iovec_t {
|
||||
void *buf;
|
||||
size_t buf_len;
|
||||
} __wasi_iovec_t;
|
||||
assert_wasi_layout(offsetof(__wasi_iovec_t, buf) == 0, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_iovec_t, buf_len) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_iovec_t, buf_len) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_iovec_t) == 16, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_iovec_t) == 4, "non-wasi data layout");
|
||||
assert_wasi_layout(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||
|
||||
/**
|
||||
* The contents of a `subscription` when type is `eventtype::clock`.
|
||||
*/
|
||||
typedef struct ALIGNED_(8) __wasi_subscription_clock_t {
|
||||
/**
|
||||
* The clock against which to compare the timestamp.
|
||||
*/
|
||||
__wasi_clockid_t clock_id;
|
||||
|
||||
uint8_t __paddings1[4];
|
||||
|
||||
/**
|
||||
* The absolute or relative timestamp.
|
||||
*/
|
||||
__wasi_timestamp_t timeout;
|
||||
|
||||
/**
|
||||
* The amount of time that the implementation may wait additionally
|
||||
* to coalesce with other events.
|
||||
*/
|
||||
__wasi_timestamp_t precision;
|
||||
|
||||
/**
|
||||
* Flags specifying whether the timeout is absolute or relative
|
||||
*/
|
||||
__wasi_subclockflags_t flags;
|
||||
|
||||
uint8_t __paddings2[4];
|
||||
|
||||
} __wasi_subscription_clock_t;
|
||||
|
||||
assert_wasi_layout(sizeof(__wasi_subscription_clock_t) == 32, "witx calculated size");
|
||||
assert_wasi_layout(_Alignof(__wasi_subscription_clock_t) == 8, "witx calculated align");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, clock_id) == 0, "witx calculated offset");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, timeout) == 8, "witx calculated offset");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, precision) == 16, "witx calculated offset");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_clock_t, flags) == 24, "witx calculated offset");
|
||||
|
||||
/**
|
||||
* The contents of a `subscription` when type is type is
|
||||
* `eventtype::fd_read` or `eventtype::fd_write`.
|
||||
*/
|
||||
typedef struct __wasi_subscription_fd_readwrite_t {
|
||||
/**
|
||||
* The file descriptor on which to wait for it to become ready for reading or writing.
|
||||
*/
|
||||
__wasi_fd_t fd;
|
||||
|
||||
} __wasi_subscription_fd_readwrite_t;
|
||||
|
||||
assert_wasi_layout(sizeof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated size");
|
||||
assert_wasi_layout(_Alignof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated align");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_fd_readwrite_t, fd) == 0, "witx calculated offset");
|
||||
|
||||
/**
|
||||
* The contents of a `subscription`.
|
||||
*/
|
||||
typedef union __wasi_subscription_u_u_t {
|
||||
__wasi_subscription_clock_t clock;
|
||||
__wasi_subscription_fd_readwrite_t fd_readwrite;
|
||||
} __wasi_subscription_u_u_t ;
|
||||
|
||||
typedef struct ALIGNED_(8) __wasi_subscription_u_t {
|
||||
__wasi_eventtype_t type;
|
||||
__wasi_subscription_u_u_t u;
|
||||
} __wasi_subscription_u_t;
|
||||
|
||||
assert_wasi_layout(sizeof(__wasi_subscription_u_t) == 40, "witx calculated size");
|
||||
assert_wasi_layout(_Alignof(__wasi_subscription_u_t) == 8, "witx calculated align");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_u_t, u) == 8, "witx calculated union offset");
|
||||
assert_wasi_layout(sizeof(__wasi_subscription_u_u_t) == 32, "witx calculated union size");
|
||||
assert_wasi_layout(_Alignof(__wasi_subscription_u_u_t) == 8, "witx calculated union align");
|
||||
|
||||
/**
|
||||
* Subscription to an event.
|
||||
*/
|
||||
typedef struct __wasi_subscription_t {
|
||||
/**
|
||||
* User-provided value that is attached to the subscription in the
|
||||
* implementation and returned through `event::userdata`.
|
||||
*/
|
||||
__wasi_userdata_t userdata;
|
||||
|
||||
/**
|
||||
* The type of the event to which to subscribe, and its contents
|
||||
*/
|
||||
__wasi_subscription_u_t u;
|
||||
|
||||
} __wasi_subscription_t;
|
||||
|
||||
assert_wasi_layout(sizeof(__wasi_subscription_t) == 48, "witx calculated size");
|
||||
assert_wasi_layout(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
|
||||
assert_wasi_layout(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
|
||||
|
||||
/* keep syncing with wasi_socket_ext.h */
|
||||
typedef enum {
|
||||
/* Used only for sock_addr_resolve hints */
|
||||
SOCKET_ANY = -1,
|
||||
SOCKET_DGRAM = 0,
|
||||
SOCKET_STREAM,
|
||||
} __wasi_sock_type_t;
|
||||
|
||||
typedef uint16_t __wasi_ip_port_t;
|
||||
|
||||
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t;
|
||||
|
||||
/* n0.n1.n2.n3 */
|
||||
typedef struct __wasi_addr_ip4_t {
|
||||
uint8_t n0;
|
||||
uint8_t n1;
|
||||
uint8_t n2;
|
||||
uint8_t n3;
|
||||
} __wasi_addr_ip4_t;
|
||||
|
||||
typedef struct __wasi_addr_ip4_port_t {
|
||||
__wasi_addr_ip4_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip4_port_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_t {
|
||||
uint16_t n0;
|
||||
uint16_t n1;
|
||||
uint16_t n2;
|
||||
uint16_t n3;
|
||||
uint16_t h0;
|
||||
uint16_t h1;
|
||||
uint16_t h2;
|
||||
uint16_t h3;
|
||||
} __wasi_addr_ip6_t;
|
||||
|
||||
typedef struct __wasi_addr_ip6_port_t {
|
||||
__wasi_addr_ip6_t addr;
|
||||
__wasi_ip_port_t port;
|
||||
} __wasi_addr_ip6_port_t;
|
||||
|
||||
typedef struct __wasi_addr_ip_t {
|
||||
__wasi_addr_type_t kind;
|
||||
union {
|
||||
__wasi_addr_ip4_t ip4;
|
||||
__wasi_addr_ip6_t ip6;
|
||||
} addr;
|
||||
} __wasi_addr_ip_t;
|
||||
|
||||
typedef struct __wasi_addr_t {
|
||||
__wasi_addr_type_t kind;
|
||||
union {
|
||||
__wasi_addr_ip4_port_t ip4;
|
||||
__wasi_addr_ip6_port_t ip6;
|
||||
} addr;
|
||||
} __wasi_addr_t;
|
||||
|
||||
typedef enum { INET4 = 0, INET6, INET_UNSPEC } __wasi_address_family_t;
|
||||
|
||||
typedef struct __wasi_addr_info_t {
|
||||
__wasi_addr_t addr;
|
||||
__wasi_sock_type_t type;
|
||||
} __wasi_addr_info_t;
|
||||
|
||||
typedef struct __wasi_addr_info_hints_t {
|
||||
__wasi_sock_type_t type;
|
||||
__wasi_address_family_t family;
|
||||
// this is to workaround lack of optional parameters
|
||||
uint8_t hints_enabled;
|
||||
} __wasi_addr_info_hints_t;
|
||||
|
||||
#undef assert_wasi_layout
|
||||
|
||||
/* clang-format on */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _PLATFORM_WASI_TYPES_H */
|
||||
@ -50,6 +50,7 @@ typedef pthread_t korp_thread;
|
||||
typedef pthread_t korp_tid;
|
||||
typedef pthread_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
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#define _LIBC_WASI_SGX_PFS_H
|
||||
|
||||
#include "bh_hashmap.h"
|
||||
#include "wasmtime_ssp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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})
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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})
|
||||
|
||||
|
||||
@ -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*/
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
143
core/shared/platform/windows/win_clock.c
Normal file
143
core/shared/platform/windows/win_clock.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_extension.h"
|
||||
#include <winternl.h>
|
||||
#include "win_util.h"
|
||||
|
||||
#define NANOSECONDS_PER_SECOND 1000000000ULL
|
||||
#define NANOSECONDS_PER_TICK 100
|
||||
|
||||
static __wasi_errno_t
|
||||
calculate_monotonic_clock_frequency(uint64 *out_frequency)
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
if (!QueryPerformanceFrequency(&frequency))
|
||||
return convert_windows_error_code(GetLastError());
|
||||
|
||||
*out_frequency = (uint64)frequency.QuadPart;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
static __wasi_errno_t
|
||||
get_performance_counter_value(uint64 *out_counter)
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
if (!QueryPerformanceCounter(&counter))
|
||||
return convert_windows_error_code(GetLastError());
|
||||
|
||||
*out_counter = counter.QuadPart;
|
||||
return __WASI_ESUCCESS;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
os_clock_res_get(__wasi_clockid_t clock_id, __wasi_timestamp_t *resolution)
|
||||
{
|
||||
__wasi_errno_t error = __WASI_ESUCCESS;
|
||||
|
||||
switch (clock_id) {
|
||||
case __WASI_CLOCK_MONOTONIC:
|
||||
{
|
||||
uint64 frequency;
|
||||
error = calculate_monotonic_clock_frequency(&frequency);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
const uint64 result = (uint64)NANOSECONDS_PER_SECOND / frequency;
|
||||
*resolution = result;
|
||||
return error;
|
||||
}
|
||||
case __WASI_CLOCK_REALTIME:
|
||||
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||
{
|
||||
#if WINAPI_PARTITION_DESKTOP
|
||||
ULONG maximum_time;
|
||||
ULONG minimum_time;
|
||||
ULONG current_time;
|
||||
NTSTATUS
|
||||
status = NtQueryTimerResolution(&maximum_time, &minimum_time,
|
||||
¤t_time);
|
||||
uint64 result = (uint64)current_time * NANOSECONDS_PER_TICK;
|
||||
*resolution = result / (uint64)NANOSECONDS_PER_SECOND;
|
||||
return error;
|
||||
#else
|
||||
return __WASI_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
||||
__wasi_timestamp_t *time)
|
||||
{
|
||||
__wasi_errno_t error = __WASI_ESUCCESS;
|
||||
|
||||
switch (clock_id) {
|
||||
case __WASI_CLOCK_REALTIME:
|
||||
{
|
||||
FILETIME sys_now;
|
||||
#if NTDDI_VERSION >= NTDDI_WIN8
|
||||
GetSystemTimePreciseAsFileTime(&sys_now);
|
||||
#else
|
||||
GetSystemTimeAsFileTime(&sys_now);
|
||||
#endif
|
||||
*time = convert_filetime_to_wasi_timestamp(&sys_now);
|
||||
return BHT_OK;
|
||||
}
|
||||
case __WASI_CLOCK_MONOTONIC:
|
||||
{
|
||||
uint64 frequency;
|
||||
error = calculate_monotonic_clock_frequency(&frequency);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
uint64 counter;
|
||||
error = get_performance_counter_value(&counter);
|
||||
|
||||
if (error != __WASI_ESUCCESS)
|
||||
return error;
|
||||
|
||||
if (NANOSECONDS_PER_SECOND % frequency == 0) {
|
||||
*time = counter * NANOSECONDS_PER_SECOND / frequency;
|
||||
}
|
||||
else {
|
||||
uint64 seconds = counter / frequency;
|
||||
uint64 fractions = counter % frequency;
|
||||
*time = seconds * NANOSECONDS_PER_SECOND
|
||||
+ (fractions * NANOSECONDS_PER_SECOND) / frequency;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
|
||||
case __WASI_CLOCK_THREAD_CPUTIME_ID:
|
||||
{
|
||||
FILETIME creation_time;
|
||||
FILETIME exit_time;
|
||||
FILETIME kernel_time;
|
||||
FILETIME user_time;
|
||||
|
||||
HANDLE handle = (clock_id == __WASI_CLOCK_PROCESS_CPUTIME_ID)
|
||||
? GetCurrentProcess()
|
||||
: GetCurrentThread();
|
||||
|
||||
if (!GetProcessTimes(handle, &creation_time, &exit_time,
|
||||
&kernel_time, &user_time))
|
||||
return convert_windows_error_code(GetLastError());
|
||||
|
||||
*time = convert_filetime_to_wasi_timestamp(&kernel_time)
|
||||
+ convert_filetime_to_wasi_timestamp(&user_time);
|
||||
|
||||
return error;
|
||||
}
|
||||
default:
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
}
|
||||
1497
core/shared/platform/windows/win_file.c
Normal file
1497
core/shared/platform/windows/win_file.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
96
core/shared/platform/windows/win_util.c
Normal file
96
core/shared/platform/windows/win_util.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_common.h"
|
||||
#include "win_util.h"
|
||||
|
||||
__wasi_timestamp_t
|
||||
convert_filetime_to_wasi_timestamp(LPFILETIME filetime)
|
||||
{
|
||||
// From 1601-01-01 to 1970-01-01 there are 134774 days.
|
||||
static const uint64_t NT_to_UNIX_epoch =
|
||||
134774ull * 86400ull * 1000ull * 1000ull * 1000ull;
|
||||
|
||||
ULARGE_INTEGER temp = { .HighPart = filetime->dwHighDateTime,
|
||||
.LowPart = filetime->dwLowDateTime };
|
||||
|
||||
// WASI timestamps are measured in nanoseconds whereas FILETIME structs are
|
||||
// represented in terms 100-nanosecond intervals.
|
||||
return (temp.QuadPart * 100ull) - NT_to_UNIX_epoch;
|
||||
}
|
||||
|
||||
__wasi_errno_t
|
||||
convert_windows_error_code(DWORD windows_error_code)
|
||||
{
|
||||
switch (windows_error_code) {
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_INVALID_HANDLE:
|
||||
case ERROR_NEGATIVE_SEEK:
|
||||
return __WASI_EINVAL;
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
case ERROR_PIPE_BUSY:
|
||||
return __WASI_EBUSY;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return __WASI_EACCES;
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
return __WASI_EEXIST;
|
||||
case ERROR_NO_MORE_FILES:
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_INVALID_NAME:
|
||||
return __WASI_ENOENT;
|
||||
case ERROR_PRIVILEGE_NOT_HELD:
|
||||
return __WASI_EPERM;
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
return __WASI_ENOMEM;
|
||||
case ERROR_NOACCESS:
|
||||
return __WASI_EFAULT;
|
||||
case ERROR_DIR_NOT_EMPTY:
|
||||
return __WASI_ENOTEMPTY;
|
||||
case ERROR_DIRECTORY:
|
||||
return __WASI_ENOTDIR;
|
||||
case ERROR_IO_PENDING:
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
case ERROR_INVALID_FLAGS:
|
||||
case ERROR_NO_UNICODE_TRANSLATION:
|
||||
default:
|
||||
return __WASI_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWP_DEFAULT_VPRINTF
|
||||
int
|
||||
uwp_print_to_debugger(const char *format, va_list ap)
|
||||
{
|
||||
// Provide a stack buffer which should be large enough for any realistic
|
||||
// string so we avoid making an allocation on every printf call.
|
||||
char stack_buf[2048];
|
||||
char *buf = stack_buf;
|
||||
int ret = vsnprintf(stack_buf, sizeof(stack_buf), format, ap);
|
||||
|
||||
if ((size_t)ret >= sizeof(stack_buf)) {
|
||||
// Allocate an extra byte for the null terminator.
|
||||
char *heap_buf = BH_MALLOC((unsigned int)(ret) + 1);
|
||||
buf = heap_buf;
|
||||
|
||||
if (heap_buf == NULL) {
|
||||
// Output as much as we can to the debugger if allocating a buffer
|
||||
// fails.
|
||||
OutputDebugStringA(stack_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = vsnprintf(heap_buf, (size_t)ret + 1, format, ap);
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
OutputDebugStringA(buf);
|
||||
|
||||
if (buf != stack_buf)
|
||||
BH_FREE(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
19
core/shared/platform/windows/win_util.h
Normal file
19
core/shared/platform/windows/win_util.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WIN_UTIL_H
|
||||
#define _WIN_UTIL_H
|
||||
|
||||
#include "platform_wasi_types.h"
|
||||
#include "windows.h"
|
||||
|
||||
__wasi_timestamp_t
|
||||
convert_filetime_to_wasi_timestamp(LPFILETIME filetime);
|
||||
|
||||
// Convert a Windows error code to a WASI error code
|
||||
__wasi_errno_t
|
||||
convert_windows_error_code(DWORD windows_error_code);
|
||||
|
||||
#endif /* end of _WIN_UTIL_H */
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user