diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b337b55ac..8815b9bcd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -284,7 +284,7 @@ jobs: - name: Setup `wasmtime` uses: bytecodealliance/actions/wasmtime/setup@v1 with: - version: "38.0.3" + version: "40.0.2" - name: Setup wasi-libc run: | cmake -S . -B build -G Ninja \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 3da53accd..dd473e8a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,8 @@ elseif(TARGET_TRIPLE MATCHES "-wasip2$") set(SHARED ON) elseif(TARGET_TRIPLE MATCHES "-wasip3$") set(WASI p3) - set(SHARED ON) + # TODO: wasip3_thread_start.s also uses non-position-independent code. + set(SHARED OFF) else() message(FATAL_ERROR "Unknown WASI target triple: ${TARGET_TRIPLE}") endif() @@ -87,6 +88,9 @@ endif() if(TARGET_TRIPLE MATCHES "-threads$") set(THREADS ON) add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec -matomics) +elseif(TARGET_TRIPLE MATCHES "-wasip3$") + set(THREADS OFF) + add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec -matomics) else() set(THREADS OFF) add_compile_options(-mthread-model single) diff --git a/cmake/ba-download.cmake b/cmake/ba-download.cmake index c3e2dc46f..2baba8337 100644 --- a/cmake/ba-download.cmake +++ b/cmake/ba-download.cmake @@ -15,11 +15,23 @@ function(ba_download target repo version) endif() if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") - set(os macos) + if (target STREQUAL wkg) + set(os apple-darwin) + else() + set(os macos) + endif() elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") - set(os linux) + if (target STREQUAL wkg) + set(os unknown-linux-gnu) + else() + set(os linux) + endif() elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") - set(os windows) + if (target STREQUAL wkg) + set(os pc-windows-gnu) + else() + set(os windows) + endif() else() set(os "UNKNOWN_OS") message(WARNING "Unsupported system ${CMAKE_HOST_SYSTEM_NAME} for ${target}") @@ -34,20 +46,50 @@ function(ba_download target repo version) set(fmt tar.gz) endif() - if (target STREQUAL wit-bindgen OR target STREQUAL wasm-tools) + if (target STREQUAL wit-bindgen OR target STREQUAL wasm-tools OR target STREQUAL wkg) set(tag v${version}) else() set(tag ${version}) endif() + message(STATUS "Using ${target} ${version} for ${arch}-${os} from ${repo}") - ExternalProject_Add( - ${target} - EXCLUDE_FROM_ALL ON - URL "${repo}/releases/download/${tag}/${target}-${version}-${arch}-${os}.${fmt}" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - ) + if (target STREQUAL wkg) + # wkg ships a single binary rather than an archive + if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(download_name "${target}-${arch}-${os}.exe") + else() + set(download_name "${target}-${arch}-${os}") + endif() + ExternalProject_Add( + ${target} + EXCLUDE_FROM_ALL ON + URL "${repo}/releases/download/${tag}/${target}-${arch}-${os}" + DOWNLOAD_NO_EXTRACT ON + DOWNLOAD_NAME ${download_name} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + + # Make the binary executable on Unix-like systems + if (NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + ExternalProject_Add_Step( + ${target} chmod-executable + COMMAND chmod +x + DEPENDEES download + DEPENDERS build + ) + endif() + else() + ExternalProject_Add( + ${target} + EXCLUDE_FROM_ALL ON + URL "${repo}/releases/download/${tag}/${target}-${version}-${arch}-${os}.${fmt}" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + endif() endfunction() diff --git a/cmake/bindings.cmake b/cmake/bindings.cmake index 016cf398d..88e7d4660 100644 --- a/cmake/bindings.cmake +++ b/cmake/bindings.cmake @@ -4,6 +4,8 @@ if (NOT BINDINGS_TARGET) return() endif() +include(ExternalProject) + # If `wit-bindgen` is on the system and has the right version, favor that, # otherwise download a known good version. find_program(WIT_BINDGEN_EXECUTABLE NAMES wit-bindgen) @@ -15,8 +17,8 @@ if(WIT_BINDGEN_EXECUTABLE) OUTPUT_VARIABLE WIT_BINDGEN_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT (WIT_BINDGEN_VERSION MATCHES "0\\.48\\.0")) - message(WARNING "wit-bindgen version 0.48.0 is required, found: ${WIT_BINDGEN_VERSION}") + if (NOT (WIT_BINDGEN_VERSION MATCHES "0\\.51\\.0")) + message(WARNING "wit-bindgen version 0.51.0 is required, found: ${WIT_BINDGEN_VERSION}") set(WIT_BINDGEN_EXECUTABLE "") endif() endif() @@ -26,7 +28,7 @@ if (NOT WIT_BINDGEN_EXECUTABLE) ba_download( wit-bindgen "https://github.com/bytecodealliance/wit-bindgen" - "0.48.0" + "0.51.0" ) ExternalProject_Get_Property(wit-bindgen SOURCE_DIR) set(wit_bindgen "${SOURCE_DIR}/wit-bindgen") @@ -35,20 +37,54 @@ else() set(wit_bindgen ${WIT_BINDGEN_EXECUTABLE}) endif() -include(ExternalProject) -set(p2 0.2.0) -ExternalProject_Add( - wasip2-wits - URL https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v${p2}.tar.gz - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - EXCLUDE_FROM_ALL TRUE -) -ExternalProject_Get_Property(wasip2-wits SOURCE_DIR) -set(wasip2_wit_dir ${SOURCE_DIR}/wit) +# If `wkg` is on the system and has the right version, favor that, +# otherwise download a known good version. +find_program(WKG_EXECUTABLE NAMES wkg) +if(WKG_EXECUTABLE) + message(STATUS "Found wkg: ${WKG_EXECUTABLE}") + + execute_process( + COMMAND ${WKG_EXECUTABLE} --version + OUTPUT_VARIABLE WKG_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if (NOT (WKG_VERSION MATCHES "0\\.13\\.0")) + message(WARNING "wkg version 0.13.0 is required, found: ${WKG_VERSION}") + set(WKG_EXECUTABLE "") + endif() +endif() + +if (NOT WKG_EXECUTABLE) + include(ba-download) + ba_download( + wkg + "https://github.com/bytecodealliance/wasm-pkg-tools" + "0.13.0" + ) + ExternalProject_Get_Property(wkg DOWNLOADED_FILE) + set(wkg_bin ${DOWNLOADED_FILE}) +else() + add_custom_target(wkg) + set(wkg_bin ${WKG_EXECUTABLE}) +endif() + set(bottom_half "${CMAKE_SOURCE_DIR}/libc-bottom-half") +set(wasip2_wit_dir ${CMAKE_CURRENT_BINARY_DIR}/wasi/p2/wit) +set(wasip2-version 0.2.0) +file(MAKE_DIRECTORY ${wasip2_wit_dir}) +configure_file(${CMAKE_SOURCE_DIR}/wasi/wasi-libc-wasip2.wit.in ${wasip2_wit_dir}/wasi-libc-wasip2.wit) +set(wasip2_stamp ${CMAKE_CURRENT_BINARY_DIR}/wasi/p2/.wit-fetch-stamp) +add_custom_command( + OUTPUT ${wasip2_stamp} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/wasi/p2 + COMMAND ${wkg_bin} wit fetch + COMMAND ${CMAKE_COMMAND} -E touch ${wasip2_stamp} + WORKING_DIRECTORY ${wasip2_wit_dir}/.. + DEPENDS wkg ${wasip2_wit_dir}/wasi-libc-wasip2.wit + COMMENT "Fetching WASI P2 dependencies" +) +add_custom_target(wasip2-wits DEPENDS ${wasip2_stamp}) add_custom_target( bindings-p2 COMMAND @@ -56,80 +92,84 @@ add_custom_target( --autodrop-borrows yes --rename-world wasip2 --type-section-suffix __wasi_libc - --world wasi:cli/imports@${p2} - --rename wasi:clocks/monotonic-clock@${p2}=monotonic_clock - --rename wasi:clocks/wall-clock@${p2}=wall_clock - --rename wasi:filesystem/preopens@${p2}=filesystem_preopens - --rename wasi:filesystem/types@${p2}=filesystem - --rename wasi:io/error@${p2}=io_error - --rename wasi:io/poll@${p2}=poll - --rename wasi:io/streams@${p2}=streams - --rename wasi:random/insecure-seed@${p2}=random_insecure_seed - --rename wasi:random/insecure@${p2}=random_insecure - --rename wasi:random/random@${p2}=random - --rename wasi:sockets/instance-network@${p2}=instance_network - --rename wasi:sockets/ip-name-lookup@${p2}=ip_name_lookup - --rename wasi:sockets/network@${p2}=network - --rename wasi:sockets/tcp-create-socket@${p2}=tcp_create_socket - --rename wasi:sockets/tcp@${p2}=tcp - --rename wasi:sockets/udp-create-socket@${p2}=udp_create_socket - --rename wasi:sockets/udp@${p2}=udp - --rename wasi:cli/environment@${p2}=environment - --rename wasi:cli/exit@${p2}=exit - --rename wasi:cli/stdin@${p2}=stdin - --rename wasi:cli/stdout@${p2}=stdout - --rename wasi:cli/stderr@${p2}=stderr - --rename wasi:cli/terminal-input@${p2}=terminal_input - --rename wasi:cli/terminal-output@${p2}=terminal_output - --rename wasi:cli/terminal-stdin@${p2}=terminal_stdin - --rename wasi:cli/terminal-stdout@${p2}=terminal_stdout - --rename wasi:cli/terminal-stderr@${p2}=terminal_stderr + --world wasi:cli/imports@${wasip2-version} + --rename wasi:clocks/monotonic-clock@${wasip2-version}=monotonic_clock + --rename wasi:clocks/wall-clock@${wasip2-version}=wall_clock + --rename wasi:filesystem/preopens@${wasip2-version}=filesystem_preopens + --rename wasi:filesystem/types@${wasip2-version}=filesystem + --rename wasi:io/error@${wasip2-version}=io_error + --rename wasi:io/poll@${wasip2-version}=poll + --rename wasi:io/streams@${wasip2-version}=streams + --rename wasi:random/insecure-seed@${wasip2-version}=random_insecure_seed + --rename wasi:random/insecure@${wasip2-version}=random_insecure + --rename wasi:random/random@${wasip2-version}=random + --rename wasi:sockets/instance-network@${wasip2-version}=instance_network + --rename wasi:sockets/ip-name-lookup@${wasip2-version}=ip_name_lookup + --rename wasi:sockets/network@${wasip2-version}=network + --rename wasi:sockets/tcp-create-socket@${wasip2-version}=tcp_create_socket + --rename wasi:sockets/tcp@${wasip2-version}=tcp + --rename wasi:sockets/udp-create-socket@${wasip2-version}=udp_create_socket + --rename wasi:sockets/udp@${wasip2-version}=udp + --rename wasi:cli/environment@${wasip2-version}=environment + --rename wasi:cli/exit@${wasip2-version}=exit + --rename wasi:cli/stdin@${wasip2-version}=stdin + --rename wasi:cli/stdout@${wasip2-version}=stdout + --rename wasi:cli/stderr@${wasip2-version}=stderr + --rename wasi:cli/terminal-input@${wasip2-version}=terminal_input + --rename wasi:cli/terminal-output@${wasip2-version}=terminal_output + --rename wasi:cli/terminal-stdin@${wasip2-version}=terminal_stdin + --rename wasi:cli/terminal-stdout@${wasip2-version}=terminal_stdout + --rename wasi:cli/terminal-stderr@${wasip2-version}=terminal_stderr ${wasip2_wit_dir} COMMAND cmake -E copy wasip2.h ${bottom_half}/headers/public/wasi/__generated_wasip2.h COMMAND cmake -E copy wasip2_component_type.o ${bottom_half}/sources COMMAND cmake -E copy wasip2.c ${bottom_half}/sources - DEPENDS wit-bindgen wasip2-wits + DEPENDS wit-bindgen wkg wasip2-wits ) -set(p3 0.3.0-rc-2025-09-16) -ExternalProject_Add( - wasip3-wits - URL https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v${p3}.tar.gz - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - EXCLUDE_FROM_ALL TRUE +set(wasip3_wit_dir ${CMAKE_CURRENT_BINARY_DIR}/wasi/p3/wit) +set(wasip3-version 0.3.0-rc-2026-01-06) +file(MAKE_DIRECTORY ${wasip3_wit_dir}) +configure_file(${CMAKE_SOURCE_DIR}/wasi/wasi-libc-wasip3.wit.in ${wasip3_wit_dir}/wasi-libc-wasip3.wit) +set(wasip3_stamp ${CMAKE_CURRENT_BINARY_DIR}/wasi/p3/.wit-fetch-stamp) +add_custom_command( + OUTPUT ${wasip3_stamp} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/wasi/p3 + COMMAND ${wkg_bin} wit fetch + COMMAND ${CMAKE_COMMAND} -E touch ${wasip3_stamp} + WORKING_DIRECTORY ${wasip3_wit_dir}/.. + DEPENDS wkg ${wasip3_wit_dir}/wasi-libc-wasip3.wit + COMMENT "Fetching WASI P3 dependencies" ) -ExternalProject_Get_Property(wasip3-wits SOURCE_DIR) -set(wasip3_wit_dir ${SOURCE_DIR}/wit-0.3.0-draft) - +add_custom_target(wasip3-wits DEPENDS ${wasip3_stamp}) add_custom_target( bindings-p3 COMMAND ${wit_bindgen} c + --generate-threading-helpers --autodrop-borrows yes --rename-world wasip3 --type-section-suffix __wasi_libc - --world wasi:cli/imports@${p3} - --rename wasi:clocks/monotonic-clock@${p3}=monotonic_clock - --rename wasi:clocks/wall-clock@${p3}=wall_clock - --rename wasi:filesystem/preopens@${p3}=filesystem_preopens - --rename wasi:filesystem/types@${p3}=filesystem - --rename wasi:random/insecure-seed@${p3}=random_insecure_seed - --rename wasi:random/insecure@${p3}=random_insecure - --rename wasi:random/random@${p3}=random - --rename wasi:sockets/types@${p3}=sockets - --rename wasi:sockets/ip-name-lookup@${p3}=ip_name_lookup - --rename wasi:cli/environment@${p3}=environment - --rename wasi:cli/exit@${p3}=exit - --rename wasi:cli/stdin@${p3}=stdin - --rename wasi:cli/stdout@${p3}=stdout - --rename wasi:cli/stderr@${p3}=stderr - --rename wasi:cli/terminal-input@${p3}=terminal_input - --rename wasi:cli/terminal-output@${p3}=terminal_output - --rename wasi:cli/terminal-stdin@${p3}=terminal_stdin - --rename wasi:cli/terminal-stdout@${p3}=terminal_stdout - --rename wasi:cli/terminal-stderr@${p3}=terminal_stderr + --world wasi:cli/imports@${wasip3-version} + --rename wasi:clocks/monotonic-clock@${wasip3-version}=monotonic_clock + --rename wasi:clocks/system-clock@${wasip3-version}=system_clock + --rename wasi:filesystem/preopens@${wasip3-version}=filesystem_preopens + --rename wasi:filesystem/types@${wasip3-version}=filesystem + --rename wasi:random/insecure-seed@${wasip3-version}=random_insecure_seed + --rename wasi:random/insecure@${wasip3-version}=random_insecure + --rename wasi:random/random@${wasip3-version}=random + --rename wasi:sockets/types@${wasip3-version}=sockets + --rename wasi:sockets/ip-name-lookup@${wasip3-version}=ip_name_lookup + --rename wasi:cli/environment@${wasip3-version}=environment + --rename wasi:cli/exit@${wasip3-version}=exit + --rename wasi:cli/stdin@${wasip3-version}=stdin + --rename wasi:cli/stdout@${wasip3-version}=stdout + --rename wasi:cli/stderr@${wasip3-version}=stderr + --rename wasi:cli/terminal-input@${wasip3-version}=terminal_input + --rename wasi:cli/terminal-output@${wasip3-version}=terminal_output + --rename wasi:cli/terminal-stdin@${wasip3-version}=terminal_stdin + --rename wasi:cli/terminal-stdout@${wasip3-version}=terminal_stdout + --rename wasi:cli/terminal-stderr@${wasip3-version}=terminal_stderr ${wasip3_wit_dir} COMMAND cmake -E copy wasip3.h ${bottom_half}/headers/public/wasi/__generated_wasip3.h COMMAND cmake -E copy wasip3_component_type.o ${bottom_half}/sources @@ -139,12 +179,18 @@ add_custom_target( add_custom_target(bindings DEPENDS bindings-p2 bindings-p3) +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(SED_INPLACE_ARGS -i '') +else() + set(SED_INPLACE_ARGS -i) +endif() + function(wit_bindgen_edit p) add_custom_target( bindings-${p}-edit - COMMAND sed -i "" "'s_#include .wasi${p}\.h._#include \"wasi/wasi${p}.h\"_'" ${bottom_half}/sources/wasi${p}.c - COMMAND sed -i "" "s/extern void exit_exit/_Noreturn extern void exit_exit/" ${bottom_half}/headers/public/wasi/__generated_wasi${p}.h - COMMAND sed -i "" "s/extern void __wasm_import_exit_exit/_Noreturn extern void __wasm_import_exit_exit/" ${bottom_half}/sources/wasi${p}.c + COMMAND sed ${SED_INPLACE_ARGS} "'s_#include .wasi${p}\.h._#include \"wasi/wasi${p}.h\"_'" ${bottom_half}/sources/wasi${p}.c + COMMAND sed ${SED_INPLACE_ARGS} "s/extern void exit_exit/_Noreturn extern void exit_exit/" ${bottom_half}/headers/public/wasi/__generated_wasi${p}.h + COMMAND sed ${SED_INPLACE_ARGS} "s/extern void __wasm_import_exit_exit/_Noreturn extern void __wasm_import_exit_exit/" ${bottom_half}/sources/wasi${p}.c DEPENDS bindings-${p} ) add_dependencies(bindings bindings-${p}-edit) diff --git a/expected/wasm32-wasip2/defined-symbols.txt b/expected/wasm32-wasip2/defined-symbols.txt index 1475ea0bb..1b59fe560 100644 --- a/expected/wasm32-wasip2/defined-symbols.txt +++ b/expected/wasm32-wasip2/defined-symbols.txt @@ -1504,6 +1504,7 @@ wasip2_list_u32_free wasip2_list_u8_free wasip2_option_string_free wasip2_string_dup +wasip2_string_dup_n wasip2_string_free wasip2_string_from_c wasip2_string_set diff --git a/expected/wasm32-wasip3/defined-symbols.txt b/expected/wasm32-wasip3/defined-symbols.txt index 81a03a483..43887c518 100644 --- a/expected/wasm32-wasip3/defined-symbols.txt +++ b/expected/wasm32-wasip3/defined-symbols.txt @@ -646,7 +646,7 @@ filesystem_method_descriptor_sync_data filesystem_method_descriptor_unlink_file_at filesystem_method_descriptor_write_via_stream filesystem_new_timestamp_free -filesystem_option_datetime_free +filesystem_option_instant_free filesystem_preopens_get_directories filesystem_preopens_list_tuple2_own_descriptor_string_free filesystem_preopens_tuple2_own_descriptor_string_free @@ -1459,31 +1459,30 @@ vswprintf vswscanf vwprintf vwscanf -wall_clock_get_resolution -wall_clock_now +wasi_clocks_system_clock_get_resolution +wasi_clocks_system_clock_now wasip3_backpressure_dec wasip3_backpressure_inc -wasip3_backpressure_set -wasip3_context_get -wasip3_context_set +wasip3_context_get_0 +wasip3_context_set_0 wasip3_list_string_free wasip3_list_tuple2_string_string_free wasip3_list_u8_free wasip3_option_string_free wasip3_string_dup +wasip3_string_dup_n wasip3_string_free wasip3_string_set wasip3_subtask_cancel wasip3_subtask_drop wasip3_task_cancel +wasip3_thread_yield wasip3_tuple2_string_string_free wasip3_waitable_join wasip3_waitable_set_drop wasip3_waitable_set_new wasip3_waitable_set_poll wasip3_waitable_set_wait -wasip3_yield -wasip3_yield_cancellable wcpcpy wcpncpy wcrtomb diff --git a/expected/wasm32-wasip3/predefined-macros.txt b/expected/wasm32-wasip3/predefined-macros.txt index 8f6bc4aa3..8e2f62089 100644 --- a/expected/wasm32-wasip3/predefined-macros.txt +++ b/expected/wasm32-wasip3/predefined-macros.txt @@ -2206,7 +2206,6 @@ #define UTIME_NOW (-1) #define UTIME_OMIT (-2) #define WASIP3_CALLBACK_CODE_EXIT 0 -#define WASIP3_CALLBACK_CODE_POLL(set) (3 | (set << 4)) #define WASIP3_CALLBACK_CODE_WAIT(set) (2 | (set << 4)) #define WASIP3_CALLBACK_CODE_YIELD 1 #define WASIP3_SUBTASK_HANDLE(status) ((wasip3_subtask_t) ((status) >> 4)) diff --git a/expected/wasm32-wasip3/undefined-symbols.txt b/expected/wasm32-wasip3/undefined-symbols.txt index ec4a54a33..71c91f823 100644 --- a/expected/wasm32-wasip3/undefined-symbols.txt +++ b/expected/wasm32-wasip3/undefined-symbols.txt @@ -1,9 +1,8 @@ __addtf3 __backpressure_dec __backpressure_inc -__backpressure_set -__context_get -__context_set +__context_get_0 +__context_set_0 __data_end __divtf3 __eqtf2 @@ -28,7 +27,6 @@ __subtask_drop __subtf3 __task_cancel __thread_yield -__thread_yield_cancellable __trunctfdf2 __trunctfsf2 __unordtf2 @@ -129,8 +127,8 @@ __wasm_import_terminal_output_terminal_output_drop __wasm_import_terminal_stderr_get_terminal_stderr __wasm_import_terminal_stdin_get_terminal_stdin __wasm_import_terminal_stdout_get_terminal_stdout -__wasm_import_wall_clock_get_resolution -__wasm_import_wall_clock_now +__wasm_import_wasi_clocks_system_clock_get_resolution +__wasm_import_wasi_clocks_system_clock_now filesystem_future_result_void_error_code__cancel_read filesystem_future_result_void_error_code__cancel_write filesystem_future_result_void_error_code__drop_readable diff --git a/libc-bottom-half/CMakeLists.txt b/libc-bottom-half/CMakeLists.txt index b6445f924..8802409a2 100644 --- a/libc-bottom-half/CMakeLists.txt +++ b/libc-bottom-half/CMakeLists.txt @@ -99,6 +99,7 @@ set(bottom_half_sources sources/__wasilibc_dt.c sources/__wasilibc_environ.c sources/__wasilibc_fd_renumber.c + sources/__wasilibc_init_task.s sources/__wasilibc_initialize_environ.c sources/__wasilibc_random.c sources/__wasilibc_real.c @@ -248,7 +249,7 @@ elseif (WASI STREQUAL "p3") ${wasm_tools} component embed ${wasip3_wit_dir} $ - --world wasi:cli/command@0.3.0-rc-2025-09-16 + --world wasi:cli/command@0.3.0-rc-2026-01-06 -o ${SYSROOT_LIB}/crt1-command.o DEPENDS crt1-command wasip3-wits $ wasm-tools ) diff --git a/libc-bottom-half/cloudlibc/src/common/time.h b/libc-bottom-half/cloudlibc/src/common/time.h index ece306e5a..a59bc344b 100644 --- a/libc-bottom-half/cloudlibc/src/common/time.h +++ b/libc-bottom-half/cloudlibc/src/common/time.h @@ -18,8 +18,11 @@ #if defined(__wasip1__) typedef __wasi_timestamp_t wasilibc_timestamp_t; -#elif defined(__wasip2__) || defined(__wasip3__) +#elif defined(__wasip2__) typedef wall_clock_datetime_t wasilibc_timestamp_t; +#elif defined(__wasip3__) +typedef filesystem_instant_t wasilibc_timestamp_t; +typedef monotonic_clock_mark_t monotonic_clock_instant_t; #else # error "Unknown WASI version" #endif @@ -30,15 +33,17 @@ static inline bool timespec_to_timestamp_exact( if (timespec->tv_nsec < 0 || timespec->tv_nsec >= NSEC_PER_SEC) return false; + #if defined(__wasip1__) || defined(__wasip2__) // Timestamps before the Epoch are not supported. if (timespec->tv_sec < 0) return false; + #endif #if defined(__wasip1__) // Make sure our timestamp does not overflow. return !__builtin_mul_overflow(timespec->tv_sec, NSEC_PER_SEC, timestamp) && !__builtin_add_overflow(*timestamp, timespec->tv_nsec, timestamp); -#elif defined(__wasip2__) || defined(__wasip3__) +#elif defined(__wasip2__) | defined(__wasip3__) timestamp->seconds = timespec->tv_sec; timestamp->nanoseconds = timespec->tv_nsec; return true; @@ -62,7 +67,7 @@ static inline bool timespec_to_timestamp_clamp( // Make sure our timestamp does not overflow. *timestamp = NUMERIC_MAX(__wasi_timestamp_t); } -#elif defined(__wasip2__) || defined(__wasip3__) +#elif defined(__wasip2__) if (timespec->tv_sec < 0) { // Timestamps before the Epoch are not supported. timestamp->seconds = 0; @@ -71,6 +76,9 @@ static inline bool timespec_to_timestamp_clamp( timestamp->seconds = timespec->tv_sec; timestamp->nanoseconds = timespec->tv_nsec; } +#elif defined(__wasip3__) + timestamp->seconds = timespec->tv_sec; + timestamp->nanoseconds = timespec->tv_nsec; #else # error "Unknown WASI version" #endif @@ -95,7 +103,13 @@ static inline struct timeval timestamp_to_timeval( #elif defined(__wasip2__) || defined(__wasip3__) static inline struct timespec timestamp_to_timespec( - wall_clock_datetime_t *timestamp) { + wasilibc_timestamp_t *timestamp) { +#if defined(__wasip2__) + // Check for overflow when converting unsigned to signed + if (timestamp->seconds > INT64_MAX) { + return (struct timespec){.tv_sec = INT64_MAX, .tv_nsec = NSEC_PER_SEC - 1}; + } +#endif return (struct timespec){.tv_sec = timestamp->seconds, .tv_nsec = timestamp->nanoseconds}; } @@ -155,7 +169,13 @@ static inline bool timeval_to_duration( } static inline struct timeval timestamp_to_timeval( - wall_clock_datetime_t *timestamp) { + wasilibc_timestamp_t *timestamp) { + #if defined(__wasip2__) + // Check for overflow when converting unsigned to signed + if (timestamp->seconds > INT64_MAX) { + return (struct timeval){.tv_sec = INT64_MAX, .tv_usec = USEC_PER_SEC - 1}; + } + #endif return (struct timeval){.tv_sec = timestamp->seconds, .tv_usec = timestamp->nanoseconds / 1000}; } diff --git a/libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c b/libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c index fc13322b6..b8e589055 100644 --- a/libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c +++ b/libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c @@ -13,7 +13,10 @@ int sched_yield(void) { errno = error; return -1; } -#endif +#elif defined(__wasip3__) + wasip3_thread_yield(); + return 0; +#else return 0; +#endif } - diff --git a/libc-bottom-half/cloudlibc/src/libc/sys/stat/stat_impl.h b/libc-bottom-half/cloudlibc/src/libc/sys/stat/stat_impl.h index 504b6ba7e..807eab164 100644 --- a/libc-bottom-half/cloudlibc/src/libc/sys/stat/stat_impl.h +++ b/libc-bottom-half/cloudlibc/src/libc/sys/stat/stat_impl.h @@ -66,6 +66,9 @@ static inline void to_public_stat(const __wasi_filestat_t *in, } } #elif defined(__wasip2__) || defined(__wasip3__) +#ifdef __wasip3__ +typedef filesystem_instant_t filesystem_datetime_t; +#endif static inline void to_public_stat(const filesystem_metadata_hash_value_t *metadata, const filesystem_descriptor_stat_t *in, struct stat *out) { diff --git a/libc-bottom-half/cloudlibc/src/libc/sys/time/gettimeofday.c b/libc-bottom-half/cloudlibc/src/libc/sys/time/gettimeofday.c index 08592fe92..97801a666 100644 --- a/libc-bottom-half/cloudlibc/src/libc/sys/time/gettimeofday.c +++ b/libc-bottom-half/cloudlibc/src/libc/sys/time/gettimeofday.c @@ -12,10 +12,14 @@ int gettimeofday(struct timeval *restrict tp, void *tz) { __wasi_timestamp_t ts = 0; (void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, 1000, &ts); *tp = timestamp_to_timeval(ts); -#elif defined(__wasip2__) || defined(__wasip3__) +#elif defined(__wasip2__) wall_clock_datetime_t time_result; wall_clock_now(&time_result); *tp = timestamp_to_timeval(&time_result); +#elif defined(__wasip3__) + system_clock_instant_t time_result; + system_clock_now(&time_result); + *tp = timestamp_to_timeval(&time_result); #else # error "Unsupported WASI version" #endif diff --git a/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c b/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c index 4619c169e..48445bdec 100644 --- a/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c +++ b/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c @@ -25,12 +25,16 @@ int __clock_gettime(clockid_t clock_id, struct timespec *tp) { monotonic_clock_instant_t ns = monotonic_clock_now(); *tp = instant_to_timespec(ns); } else if (clock_id == CLOCK_REALTIME) { - wall_clock_datetime_t time_result; + wasilibc_timestamp_t time_result; + #ifdef __wasip2__ wall_clock_now(&time_result); + #else + system_clock_now(&time_result); + #endif *tp = timestamp_to_timespec(&time_result); } else { errno = EINVAL; - return -1; // wasip2 only supports wall and monotonic clocks + return -1; // wasip{2,3} only supports wall and monotonic clocks } #else # error "Unsupported WASI version" diff --git a/libc-bottom-half/cloudlibc/src/libc/time/time.c b/libc-bottom-half/cloudlibc/src/libc/time/time.c index 96c09b35a..fbdb4b602 100644 --- a/libc-bottom-half/cloudlibc/src/libc/time/time.c +++ b/libc-bottom-half/cloudlibc/src/libc/time/time.c @@ -10,10 +10,14 @@ time_t time(time_t *tloc) { #if defined(__wasip1__) __wasi_timestamp_t ts = 0; (void)__wasi_clock_time_get(__WASI_CLOCKID_REALTIME, NSEC_PER_SEC, &ts); -#elif defined(__wasip2__) || defined(__wasip3__) - wall_clock_datetime_t res; +#elif defined(__wasip2__) + wasilibc_timestamp_t res; wall_clock_now(&res); uint64_t ts = (res.seconds * NSEC_PER_SEC) + res.nanoseconds; +#elif defined(__wasip3__) + wasilibc_timestamp_t res; + system_clock_now(&res); + time_t ts = (res.seconds * NSEC_PER_SEC) + res.nanoseconds; #else # error "Unsupported WASI version" #endif diff --git a/libc-bottom-half/crt/crt1-command.c b/libc-bottom-half/crt/crt1-command.c index 63e556779..6ef297592 100644 --- a/libc-bottom-half/crt/crt1-command.c +++ b/libc-bottom-half/crt/crt1-command.c @@ -18,7 +18,7 @@ __attribute__((export_name("_start"))) void _start(void) // that this shouldn't be too problematic (in theory). __attribute__((export_name("wasi:cli/run@0.2.0#run"))) int _start(void) #elif defined(__wasip3__) -__attribute__((export_name("wasi:cli/run@0.3.0-rc-2025-09-16#run"))) int +__attribute__((export_name("wasi:cli/run@0.3.0-rc-2026-01-06#run"))) int _start(void) #else #error "Unsupported WASI version" diff --git a/libc-bottom-half/headers/public/wasi/__generated_wasip2.h b/libc-bottom-half/headers/public/wasi/__generated_wasip2.h index 54ffac264..e4f14db97 100644 --- a/libc-bottom-half/headers/public/wasi/__generated_wasip2.h +++ b/libc-bottom-half/headers/public/wasi/__generated_wasip2.h @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.48.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.51.0. DO NOT EDIT! #ifndef __BINDINGS_WASIP2_H #define __BINDINGS_WASIP2_H #ifdef __cplusplus @@ -1035,16 +1035,6 @@ typedef struct ip_name_lookup_borrow_resolve_address_stream_t { int32_t __handle; } ip_name_lookup_borrow_resolve_address_stream_t; -typedef network_borrow_network_t ip_name_lookup_borrow_network_t; - -typedef struct { - bool is_err; - union { - ip_name_lookup_own_resolve_address_stream_t ok; - ip_name_lookup_error_code_t err; - } val; -} ip_name_lookup_result_own_resolve_address_stream_error_code_t; - typedef struct { bool is_some; ip_name_lookup_ip_address_t val; @@ -1060,6 +1050,16 @@ typedef struct { typedef poll_own_pollable_t ip_name_lookup_own_pollable_t; +typedef network_borrow_network_t ip_name_lookup_borrow_network_t; + +typedef struct { + bool is_err; + union { + ip_name_lookup_own_resolve_address_stream_t ok; + ip_name_lookup_error_code_t err; + } val; +} ip_name_lookup_result_own_resolve_address_stream_error_code_t; + typedef struct { uint64_t f0; uint64_t f1; @@ -1206,13 +1206,13 @@ extern bool streams_method_output_stream_write(streams_borrow_output_stream_t se // ```text // let pollable = this.subscribe(); // while !contents.is_empty() { -// // Wait for the stream to become writable -// pollable.block(); -// let Ok(n) = this.check-write(); // eliding error handling -// let len = min(n, contents.len()); -// let (chunk, rest) = contents.split_at(len); -// this.write(chunk ); // eliding error handling -// contents = rest; +// // Wait for the stream to become writable +// pollable.block(); +// let Ok(n) = this.check-write(); // eliding error handling +// let len = min(n, contents.len()); +// let (chunk, rest) = contents.split_at(len); +// this.write(chunk ); // eliding error handling +// contents = rest; // } // this.flush(); // // Wait for completion of `flush` @@ -1264,12 +1264,12 @@ extern bool streams_method_output_stream_write_zeroes(streams_borrow_output_stre // ```text // let pollable = this.subscribe(); // while num_zeroes != 0 { -// // Wait for the stream to become writable -// pollable.block(); -// let Ok(n) = this.check-write(); // eliding error handling -// let len = min(n, num_zeroes); -// this.write-zeroes(len); // eliding error handling -// num_zeroes -= len; +// // Wait for the stream to become writable +// pollable.block(); +// let Ok(n) = this.check-write(); // eliding error handling +// let len = min(n, num_zeroes); +// this.write-zeroes(len); // eliding error handling +// num_zeroes -= len; // } // this.flush(); // // Wait for completion of `flush` @@ -1562,12 +1562,12 @@ extern bool filesystem_method_descriptor_is_same_object(filesystem_borrow_descri // // Implementations are encourated to provide the following properties: // -// - If the file is not modified or replaced, the computed hash value should -// usually not change. -// - If the object is modified or replaced, the computed hash value should -// usually change. -// - The inputs to the hash should not be easily computable from the -// computed hash. +// - If the file is not modified or replaced, the computed hash value should +// usually not change. +// - If the object is modified or replaced, the computed hash value should +// usually change. +// - The inputs to the hash should not be easily computable from the +// computed hash. // // However, none of these is required. extern bool filesystem_method_descriptor_metadata_hash(filesystem_borrow_descriptor_t self, filesystem_metadata_hash_value_t *ret, filesystem_error_code_t *err); @@ -1644,10 +1644,10 @@ extern bool udp_method_udp_socket_finish_bind(udp_borrow_udp_socket_t self, udp_ // The POSIX equivalent in pseudo-code is: // ```text // if (was previously connected) { -// connect(s, AF_UNSPEC) +// connect(s, AF_UNSPEC) // } // if (remote_address is Some) { -// connect(s, remote_address) +// connect(s, remote_address) // } // ``` // @@ -2107,11 +2107,11 @@ extern tcp_own_pollable_t tcp_method_tcp_socket_subscribe(tcp_borrow_tcp_socket_ // Initiate a graceful shutdown. // // - `receive`: The socket is not expecting to receive any data from -// the peer. The `input-stream` associated with this socket will be -// closed. Any data still in the receive queue at time of calling -// this method will be discarded. +// the peer. The `input-stream` associated with this socket will be +// closed. Any data still in the receive queue at time of calling +// this method will be discarded. // - `send`: The socket has no more data to send to the peer. The `output-stream` -// associated with this socket will be closed and a FIN packet will be sent. +// associated with this socket will be closed and a FIN packet will be sent. // - `both`: Same effect as `receive` & `send` combined. // // This function is idempotent. Shutting a down a direction more than once @@ -2153,6 +2153,25 @@ extern bool tcp_method_tcp_socket_shutdown(tcp_borrow_tcp_socket_t self, tcp_shu extern bool tcp_create_socket_create_tcp_socket(tcp_create_socket_ip_address_family_t address_family, tcp_create_socket_own_tcp_socket_t *ret, tcp_create_socket_error_code_t *err); // Imported Functions from `wasi:sockets/ip-name-lookup@0.2.0` +// Returns the next address from the resolver. +// +// This function should be called multiple times. On each call, it will +// return the next address in connection order preference. If all +// addresses have been exhausted, this function returns `none`. +// +// This function never returns IPv4-mapped IPv6 addresses. +// +// # Typical errors +// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) +// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) +// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) +// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) +extern bool ip_name_lookup_method_resolve_address_stream_resolve_next_address(ip_name_lookup_borrow_resolve_address_stream_t self, ip_name_lookup_option_ip_address_t *ret, ip_name_lookup_error_code_t *err); +// Create a `pollable` which will resolve once the stream is ready for I/O. +// +// Note: this function is here for WASI Preview2 only. +// It's planned to be removed when `future` is natively supported in Preview3. +extern ip_name_lookup_own_pollable_t ip_name_lookup_method_resolve_address_stream_subscribe(ip_name_lookup_borrow_resolve_address_stream_t self); // Resolve an internet host name to a list of IP addresses. // // Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -2174,25 +2193,6 @@ extern bool tcp_create_socket_create_tcp_socket(tcp_create_socket_ip_address_fam // - // - extern bool ip_name_lookup_resolve_addresses(ip_name_lookup_borrow_network_t network, wasip2_string_t *name, ip_name_lookup_own_resolve_address_stream_t *ret, ip_name_lookup_error_code_t *err); -// Returns the next address from the resolver. -// -// This function should be called multiple times. On each call, it will -// return the next address in connection order preference. If all -// addresses have been exhausted, this function returns `none`. -// -// This function never returns IPv4-mapped IPv6 addresses. -// -// # Typical errors -// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) -// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) -// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) -// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) -extern bool ip_name_lookup_method_resolve_address_stream_resolve_next_address(ip_name_lookup_borrow_resolve_address_stream_t self, ip_name_lookup_option_ip_address_t *ret, ip_name_lookup_error_code_t *err); -// Create a `pollable` which will resolve once the stream is ready for I/O. -// -// Note: this function is here for WASI Preview2 only. -// It's planned to be removed when `future` is natively supported in Preview3. -extern ip_name_lookup_own_pollable_t ip_name_lookup_method_resolve_address_stream_subscribe(ip_name_lookup_borrow_resolve_address_stream_t self); // Imported Functions from `wasi:random/random@0.2.0` // Return `len` cryptographically-secure random or pseudo-random bytes. @@ -2434,12 +2434,12 @@ extern void ip_name_lookup_resolve_address_stream_drop_own(ip_name_lookup_own_re extern ip_name_lookup_borrow_resolve_address_stream_t ip_name_lookup_borrow_resolve_address_stream(ip_name_lookup_own_resolve_address_stream_t handle); -void ip_name_lookup_result_own_resolve_address_stream_error_code_free(ip_name_lookup_result_own_resolve_address_stream_error_code_t *ptr); - void ip_name_lookup_option_ip_address_free(ip_name_lookup_option_ip_address_t *ptr); void ip_name_lookup_result_option_ip_address_error_code_free(ip_name_lookup_result_option_ip_address_error_code_t *ptr); +void ip_name_lookup_result_own_resolve_address_stream_error_code_free(ip_name_lookup_result_own_resolve_address_stream_error_code_t *ptr); + // Sets the string `ret` to reference the input string `s` without copying it void wasip2_string_set(wasip2_string_t *ret, const char*s); @@ -2447,6 +2447,11 @@ void wasip2_string_set(wasip2_string_t *ret, const char*s); // stores it into the component model string `ret`. void wasip2_string_dup(wasip2_string_t *ret, const char*s); +// Creates a copy of the input string `s` with length `len` and +// stores it into the component model string `ret`. +// The length is specified in code units (bytes for UTF-8, 16-bit values for UTF-16). +void wasip2_string_dup_n(wasip2_string_t *ret, const char*s, size_t len); + // Deallocates the string pointed to by `ret`, deallocating // the memory behind the string. void wasip2_string_free(wasip2_string_t *ret); diff --git a/libc-bottom-half/headers/public/wasi/__generated_wasip3.h b/libc-bottom-half/headers/public/wasi/__generated_wasip3.h index 8618192ab..ffedcc86e 100644 --- a/libc-bottom-half/headers/public/wasi/__generated_wasip3.h +++ b/libc-bottom-half/headers/public/wasi/__generated_wasip3.h @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.48.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.51.0. DO NOT EDIT! #ifndef __BINDINGS_WASIP3_H #define __BINDINGS_WASIP3_H #ifdef __cplusplus @@ -36,7 +36,6 @@ typedef uint32_t wasip3_callback_code_t; #define WASIP3_CALLBACK_CODE_EXIT 0 #define WASIP3_CALLBACK_CODE_YIELD 1 #define WASIP3_CALLBACK_CODE_WAIT(set) (2 | (set << 4)) -#define WASIP3_CALLBACK_CODE_POLL(set) (3 | (set << 4)) typedef enum wasip3_event_code { WASIP3_EVENT_NONE, @@ -74,13 +73,25 @@ typedef enum wasip3_waitable_state { WASIP3_WAITABLE_CANCELLED, } wasip3_waitable_state_t; -void wasip3_backpressure_set(bool enable); void wasip3_backpressure_inc(void); void wasip3_backpressure_dec(void); -void* wasip3_context_get(void); -void wasip3_context_set(void*); -void wasip3_yield(void); -uint32_t wasip3_yield_cancellable(void); +void* wasip3_context_get_0(void); +void wasip3_context_set_0(void* value); +void wasip3_thread_yield(void); + + +void* wasip3_context_get_1(void); +void wasip3_context_set_1(void* value); +uint32_t wasip3_thread_yield_cancellable(void); +uint32_t wasip3_thread_index(void); +uint32_t wasip3_thread_new_indirect(void (*start_function)(void*), void* arg); +void wasip3_thread_switch_to(uint32_t thread); +uint32_t wasip3_thread_switch_to_cancellable(uint32_t thread); +void wasip3_thread_resume_later(uint32_t thread); +void wasip3_thread_yield_to(uint32_t thread); +uint32_t wasip3_thread_yield_to_cancellable(uint32_t thread); +void wasip3_thread_suspend(void); +uint32_t wasip3_thread_suspend_cancellable(void); @@ -195,18 +206,35 @@ typedef uint64_t wasi_clocks_types_duration_t; typedef wasi_clocks_types_duration_t monotonic_clock_duration_t; -// An instant in time, in nanoseconds. An instant is relative to an +// A mark on a monotonic clock is a number of nanoseconds since an // unspecified initial value, and can only be compared to instances from // the same monotonic-clock. -typedef uint64_t monotonic_clock_instant_t; +typedef uint64_t monotonic_clock_mark_t; -// A time and date in seconds plus nanoseconds. -typedef struct wall_clock_datetime_t { - uint64_t seconds; +typedef wasi_clocks_types_duration_t system_clock_duration_t; + +// An "instant", or "exact time", is a point in time without regard to any +// time zone: just the time since a particular external reference point, +// often called an "epoch". +// +// Here, the epoch is 1970-01-01T00:00:00Z, also known as +// [POSIX's Seconds Since the Epoch], also known as [Unix Time]. +// +// Note that even if the seconds field is negative, incrementing +// nanoseconds always represents moving forwards in time. +// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the +// instant one nanosecond before the epoch. +// For more on various different ways to represent time, see +// https://tc39.es/proposal-temporal/docs/timezone.html +// +// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 +// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time +typedef struct system_clock_instant_t { + int64_t seconds; uint32_t nanoseconds; -} wall_clock_datetime_t; +} system_clock_instant_t; -typedef wall_clock_datetime_t filesystem_datetime_t; +typedef system_clock_instant_t filesystem_instant_t; // File size or length of a region within a file. typedef uint64_t filesystem_filesize_t; @@ -301,8 +329,8 @@ typedef uint64_t filesystem_link_count_t; typedef struct { bool is_some; - filesystem_datetime_t val; -} filesystem_option_datetime_t; + filesystem_instant_t val; +} filesystem_option_instant_t; // File attributes. // @@ -319,24 +347,24 @@ typedef struct filesystem_descriptor_stat_t { // // If the `option` is none, the platform doesn't maintain an access // timestamp for this file. - filesystem_option_datetime_t data_access_timestamp; + filesystem_option_instant_t data_access_timestamp; // Last data modification timestamp. // // If the `option` is none, the platform doesn't maintain a // modification timestamp for this file. - filesystem_option_datetime_t data_modification_timestamp; + filesystem_option_instant_t data_modification_timestamp; // Last file status-change timestamp. // // If the `option` is none, the platform doesn't maintain a // status-change timestamp for this file. - filesystem_option_datetime_t status_change_timestamp; + filesystem_option_instant_t status_change_timestamp; } filesystem_descriptor_stat_t; // When setting a timestamp, this gives the value to set it to. typedef struct filesystem_new_timestamp_t { uint8_t tag; union { - filesystem_datetime_t timestamp; + filesystem_instant_t timestamp; } val; } filesystem_new_timestamp_t; @@ -594,7 +622,7 @@ typedef struct { size_t len; } filesystem_preopens_list_tuple2_own_descriptor_string_t; -typedef monotonic_clock_duration_t sockets_duration_t; +typedef wasi_clocks_types_duration_t sockets_duration_t; // Error codes. // @@ -896,7 +924,7 @@ typedef struct { uint64_t f1; } wasip3_tuple2_u64_u64_t; -// Imported Functions from `wasi:cli/environment@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/environment@0.3.0-rc-2026-01-06` // Get the POSIX-style environment variables. // // Each environment variable is provided as a pair of string variable names @@ -912,11 +940,11 @@ extern void environment_get_arguments(wasip3_list_string_t *ret); // directory, interpreting `.` as shorthand for this. extern bool environment_get_initial_cwd(wasip3_string_t *ret); -// Imported Functions from `wasi:cli/exit@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/exit@0.3.0-rc-2026-01-06` // Exit the current instance and any linked instances. _Noreturn extern void exit_exit(exit_result_void_void_t *status); -// Imported Functions from `wasi:cli/stdin@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stdin@0.3.0-rc-2026-01-06` // Return a stream for reading from stdin. // // This function returns a stream which provides data read from stdin, @@ -932,7 +960,7 @@ _Noreturn extern void exit_exit(exit_result_void_void_t *status); // reads is implementation-specific. extern void stdin_read_via_stream(stdin_tuple2_stream_u8_future_result_void_error_code_t *ret); -// Imported Functions from `wasi:cli/stdout@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stdout@0.3.0-rc-2026-01-06` // Write the given stream to stdout. // // If the stream's writable end is dropped this function will either return @@ -943,7 +971,7 @@ extern void stdin_read_via_stream(stdin_tuple2_stream_u8_future_result_void_erro // dropped and this function will return an error-code. extern wasip3_subtask_status_t stdout_write_via_stream(stdin_stream_u8_t data, stdout_result_void_error_code_t *result); -// Imported Functions from `wasi:cli/stderr@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stderr@0.3.0-rc-2026-01-06` // Write the given stream to stderr. // // If the stream's writable end is dropped this function will either return @@ -954,61 +982,53 @@ extern wasip3_subtask_status_t stdout_write_via_stream(stdin_stream_u8_t data, s // dropped and this function will return an error-code. extern wasip3_subtask_status_t stderr_write_via_stream(stdin_stream_u8_t data, stderr_result_void_error_code_t *result); -// Imported Functions from `wasi:cli/terminal-stdin@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stdin@0.3.0-rc-2026-01-06` // If stdin is connected to a terminal, return a `terminal-input` handle // allowing further interaction with it. extern bool terminal_stdin_get_terminal_stdin(terminal_stdin_own_terminal_input_t *ret); -// Imported Functions from `wasi:cli/terminal-stdout@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stdout@0.3.0-rc-2026-01-06` // If stdout is connected to a terminal, return a `terminal-output` handle // allowing further interaction with it. extern bool terminal_stdout_get_terminal_stdout(terminal_stdout_own_terminal_output_t *ret); -// Imported Functions from `wasi:cli/terminal-stderr@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stderr@0.3.0-rc-2026-01-06` // If stderr is connected to a terminal, return a `terminal-output` handle // allowing further interaction with it. extern bool terminal_stderr_get_terminal_stderr(terminal_stderr_own_terminal_output_t *ret); -// Imported Functions from `wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06` // Read the current value of the clock. // // The clock is monotonic, therefore calling this function repeatedly will // produce a sequence of non-decreasing values. // // For completeness, this function traps if it's not possible to represent -// the value of the clock in an `instant`. Consequently, implementations +// the value of the clock in a `mark`. Consequently, implementations // should ensure that the starting time is low enough to avoid the // possibility of overflow in practice. -extern monotonic_clock_instant_t monotonic_clock_now(void); +extern monotonic_clock_mark_t monotonic_clock_now(void); // Query the resolution of the clock. Returns the duration of time // corresponding to a clock tick. extern monotonic_clock_duration_t monotonic_clock_get_resolution(void); -// Wait until the specified instant has occurred. -extern wasip3_subtask_status_t monotonic_clock_wait_until(monotonic_clock_instant_t when); +// Wait until the specified mark has occurred. +extern wasip3_subtask_status_t monotonic_clock_wait_until(monotonic_clock_mark_t when); // Wait for the specified duration to elapse. extern wasip3_subtask_status_t monotonic_clock_wait_for(monotonic_clock_duration_t how_long); -// Imported Functions from `wasi:clocks/wall-clock@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:clocks/system-clock@0.3.0-rc-2026-01-06` // Read the current value of the clock. // // This clock is not monotonic, therefore calling this function repeatedly // will not necessarily produce a sequence of non-decreasing values. // -// The returned timestamps represent the number of seconds since -// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], -// also known as [Unix Time]. -// -// The nanoseconds field of the output is always less than 1000000000. -// -// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 -// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time -extern void wall_clock_now(wall_clock_datetime_t *ret); -// Query the resolution of the clock. -// // The nanoseconds field of the output is always less than 1000000000. -extern void wall_clock_get_resolution(wall_clock_datetime_t *ret); +extern void system_clock_now(system_clock_instant_t *ret); +// Query the resolution of the clock. Returns the smallest duration of time +// that the implementation permits distinguishing. +extern system_clock_duration_t system_clock_get_resolution(void); -// Imported Functions from `wasi:filesystem/types@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:filesystem/types@0.3.0-rc-2026-01-06` // Return a stream for reading from a file. // // Multiple read, write, and append streams may be active on the same open @@ -1220,11 +1240,11 @@ extern wasip3_subtask_status_t filesystem_method_descriptor_metadata_hash(filesy // This performs the same hash computation as `metadata-hash`. extern wasip3_subtask_status_t filesystem_method_descriptor_metadata_hash_at(filesystem_borrow_descriptor_t self, filesystem_path_flags_t path_flags, wasip3_string_t path, filesystem_result_metadata_hash_value_error_code_t *result); -// Imported Functions from `wasi:filesystem/preopens@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:filesystem/preopens@0.3.0-rc-2026-01-06` // Return the set of preopened directories, and their paths. extern void filesystem_preopens_get_directories(filesystem_preopens_list_tuple2_own_descriptor_string_t *ret); -// Imported Functions from `wasi:sockets/types@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:sockets/types@0.3.0-rc-2026-01-06` // Create a new TCP socket. // // Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. @@ -1737,7 +1757,7 @@ extern bool sockets_method_udp_socket_set_receive_buffer_size(sockets_borrow_udp extern bool sockets_method_udp_socket_get_send_buffer_size(sockets_borrow_udp_socket_t self, uint64_t *ret, sockets_error_code_t *err); extern bool sockets_method_udp_socket_set_send_buffer_size(sockets_borrow_udp_socket_t self, uint64_t value, sockets_error_code_t *err); -// Imported Functions from `wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06` // Resolve an internet host name to a list of IP addresses. // // Unicode domain names are automatically converted to ASCII using IDNA encoding. @@ -1762,7 +1782,7 @@ extern bool sockets_method_udp_socket_set_send_buffer_size(sockets_borrow_udp_so // - extern wasip3_subtask_status_t ip_name_lookup_resolve_addresses(wasip3_string_t name, ip_name_lookup_result_list_ip_address_error_code_t *result); -// Imported Functions from `wasi:random/random@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/random@0.3.0-rc-2026-01-06` // Return `len` cryptographically-secure random or pseudo-random bytes. // // This function must produce data at least as cryptographically secure and @@ -1782,7 +1802,7 @@ extern void random_get_random_bytes(uint64_t len, wasip3_list_u8_t *ret); // represented as a `u64`. extern uint64_t random_get_random_u64(void); -// Imported Functions from `wasi:random/insecure@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/insecure@0.3.0-rc-2026-01-06` // Return `len` insecure pseudo-random bytes. // // This function is not cryptographically secure. Do not use it for @@ -1798,7 +1818,7 @@ extern void random_insecure_get_insecure_random_bytes(uint64_t len, wasip3_list_ // `get-insecure-random-bytes`, represented as a `u64`. extern uint64_t random_insecure_get_insecure_random_u64(void); -// Imported Functions from `wasi:random/insecure-seed@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/insecure-seed@0.3.0-rc-2026-01-06` // Return a 128-bit value that may contain a pseudo-random value. // // The returned value is not required to be computed from a CSPRNG, and may @@ -1872,7 +1892,7 @@ void terminal_stdout_option_own_terminal_output_free(terminal_stdout_option_own_ void terminal_stderr_option_own_terminal_output_free(terminal_stderr_option_own_terminal_output_t *ptr); -void filesystem_option_datetime_free(filesystem_option_datetime_t *ptr); +void filesystem_option_instant_free(filesystem_option_instant_t *ptr); void filesystem_descriptor_stat_free(filesystem_descriptor_stat_t *ptr); @@ -2021,6 +2041,11 @@ void wasip3_string_set(wasip3_string_t *ret, const char*s); // stores it into the component model string `ret`. void wasip3_string_dup(wasip3_string_t *ret, const char*s); +// Creates a copy of the input string `s` with length `len` and +// stores it into the component model string `ret`. +// The length is specified in code units (bytes for UTF-8, 16-bit values for UTF-16). +void wasip3_string_dup_n(wasip3_string_t *ret, const char*s, size_t len); + // Deallocates the string pointed to by `ret`, deallocating // the memory behind the string. void wasip3_string_free(wasip3_string_t *ret); diff --git a/libc-bottom-half/sources/__wasilibc_init_task.s b/libc-bottom-half/sources/__wasilibc_init_task.s new file mode 100644 index 000000000..e34c310e7 --- /dev/null +++ b/libc-bottom-half/sources/__wasilibc_init_task.s @@ -0,0 +1,68 @@ + .text + + .export_name __wasilibc_init_task, __wasilibc_init_task + .export_name __wasilibc_init_task_async, __wasilibc_init_task_async + + .globaltype __init_stack_pointer, i32 + .globaltype __init_tls_base, i32 + .globaltype __tls_size, i32, immutable + .globaltype __tls_align, i32, immutable + + .functype __wasm_component_model_builtin_context_set_0 (i32) -> () + .import_module __wasm_component_model_builtin_context_set_0, "$root" + .import_name __wasm_component_model_builtin_context_set_0, "[context-set-0]" + .functype __wasm_component_model_builtin_context_set_1 (i32) -> () + .import_module __wasm_component_model_builtin_context_set_1, "$root" + .import_name __wasm_component_model_builtin_context_set_1, "[context-set-1]" + + .functype malloc (i32) -> (i32) + .functype __copy_tls (i32) -> (i32) + + .globl __wasilibc_init_task + .type __wasilibc_init_task,@function + .globl __wasilibc_init_task_async + .type __wasilibc_init_task_async,@function + +__wasilibc_init_task: + .functype __wasilibc_init_task () -> () + + global.get __init_stack_pointer + call __wasm_component_model_builtin_context_set_0 + + global.get __init_tls_base + call __wasm_component_model_builtin_context_set_1 + + # Allocate a new TLS area + global.get __tls_size + # TODO align + call malloc + call __copy_tls + call __wasm_component_model_builtin_context_set_1 + + end_function + +__wasilibc_init_task_async: + .functype __wasilibc_init_task_async () -> () + + # malloc and __init_tls may use the stack pointer and TLS base, so set those first + # to the statically-allocated values used for synchronous tasks. + global.get __init_stack_pointer + call __wasm_component_model_builtin_context_set_0 + + global.get __init_tls_base + call __wasm_component_model_builtin_context_set_1 + + # Allocate a new stack + # Value chosen for parity with __default_stacksize in pthread_impl.h + i32.const 131072 + call malloc + call __wasm_component_model_builtin_context_set_0 + + # Allocate a new TLS area + global.get __tls_size + # TODO align + call malloc + call __copy_tls + call __wasm_component_model_builtin_context_set_1 + + end_function diff --git a/libc-bottom-half/sources/wasip2.c b/libc-bottom-half/sources/wasip2.c index ef7c5d627..ef3f67ba2 100644 --- a/libc-bottom-half/sources/wasip2.c +++ b/libc-bottom-half/sources/wasip2.c @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.48.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.51.0. DO NOT EDIT! #include "wasi/wasip2.h" #include #include @@ -387,15 +387,15 @@ extern void __wasm_import_tcp_create_socket_create_tcp_socket(int32_t, uint8_t * // Imported Functions from `wasi:sockets/ip-name-lookup@0.2.0` -__attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.2.0"), __import_name__("resolve-addresses"))) -extern void __wasm_import_ip_name_lookup_resolve_addresses(int32_t, uint8_t *, size_t, uint8_t *); - __attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.2.0"), __import_name__("[method]resolve-address-stream.resolve-next-address"))) extern void __wasm_import_ip_name_lookup_method_resolve_address_stream_resolve_next_address(int32_t, uint8_t *); __attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.2.0"), __import_name__("[method]resolve-address-stream.subscribe"))) extern int32_t __wasm_import_ip_name_lookup_method_resolve_address_stream_subscribe(int32_t); +__attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.2.0"), __import_name__("resolve-addresses"))) +extern void __wasm_import_ip_name_lookup_resolve_addresses(int32_t, uint8_t *, size_t, uint8_t *); + // Imported Functions from `wasi:random/random@0.2.0` __attribute__((__import_module__("wasi:random/random@0.2.0"), __import_name__("get-random-bytes"))) @@ -1002,12 +1002,6 @@ ip_name_lookup_borrow_resolve_address_stream_t ip_name_lookup_borrow_resolve_add return (ip_name_lookup_borrow_resolve_address_stream_t) { arg.__handle }; } -void ip_name_lookup_result_own_resolve_address_stream_error_code_free(ip_name_lookup_result_own_resolve_address_stream_error_code_t *ptr) { - if (!ptr->is_err) { - } else { - } -} - void ip_name_lookup_option_ip_address_free(ip_name_lookup_option_ip_address_t *ptr) { if (ptr->is_some) { ip_name_lookup_ip_address_free(&ptr->val); @@ -1021,6 +1015,12 @@ void ip_name_lookup_result_option_ip_address_error_code_free(ip_name_lookup_resu } } +void ip_name_lookup_result_own_resolve_address_stream_error_code_free(ip_name_lookup_result_own_resolve_address_stream_error_code_t *ptr) { + if (!ptr->is_err) { + } else { + } +} + void wasip2_string_set(wasip2_string_t *ret, const char*s) { ret->ptr = (uint8_t*) s; ret->len = strlen(s); @@ -1032,6 +1032,12 @@ void wasip2_string_dup(wasip2_string_t *ret, const char*s) { memcpy(ret->ptr, s, ret->len * 1); } +void wasip2_string_dup_n(wasip2_string_t *ret, const char*s, size_t len) { + ret->len = len; + ret->ptr = (uint8_t*) cabi_realloc(NULL, 0, 1, ret->len * 1); + memcpy(ret->ptr, s, ret->len * 1); +} + void wasip2_string_free(wasip2_string_t *ret) { if (ret->len > 0) { free(ret->ptr); @@ -4195,33 +4201,6 @@ bool tcp_create_socket_create_tcp_socket(tcp_create_socket_ip_address_family_t a } } -bool ip_name_lookup_resolve_addresses(ip_name_lookup_borrow_network_t network, wasip2_string_t *name, ip_name_lookup_own_resolve_address_stream_t *ret, ip_name_lookup_error_code_t *err) { - __attribute__((__aligned__(4))) - uint8_t ret_area[8]; - uint8_t *ptr = (uint8_t *) &ret_area; - __wasm_import_ip_name_lookup_resolve_addresses((network).__handle, (uint8_t *) (*name).ptr, (*name).len, ptr); - ip_name_lookup_result_own_resolve_address_stream_error_code_t result; - switch ((int32_t) *((uint8_t*) (ptr + 0))) { - case 0: { - result.is_err = false; - result.val.ok = (ip_name_lookup_own_resolve_address_stream_t) { *((int32_t*) (ptr + 4)) }; - break; - } - case 1: { - result.is_err = true; - result.val.err = (int32_t) *((uint8_t*) (ptr + 4)); - break; - } - } - if (!result.is_err) { - *ret = result.val.ok; - return 1; - } else { - *err = result.val.err; - return 0; - } -} - bool ip_name_lookup_method_resolve_address_stream_resolve_next_address(ip_name_lookup_borrow_resolve_address_stream_t self, ip_name_lookup_option_ip_address_t *ret, ip_name_lookup_error_code_t *err) { __attribute__((__aligned__(2))) uint8_t ret_area[22]; @@ -4294,6 +4273,33 @@ ip_name_lookup_own_pollable_t ip_name_lookup_method_resolve_address_stream_subsc return (ip_name_lookup_own_pollable_t) { ret }; } +bool ip_name_lookup_resolve_addresses(ip_name_lookup_borrow_network_t network, wasip2_string_t *name, ip_name_lookup_own_resolve_address_stream_t *ret, ip_name_lookup_error_code_t *err) { + __attribute__((__aligned__(4))) + uint8_t ret_area[8]; + uint8_t *ptr = (uint8_t *) &ret_area; + __wasm_import_ip_name_lookup_resolve_addresses((network).__handle, (uint8_t *) (*name).ptr, (*name).len, ptr); + ip_name_lookup_result_own_resolve_address_stream_error_code_t result; + switch ((int32_t) *((uint8_t*) (ptr + 0))) { + case 0: { + result.is_err = false; + result.val.ok = (ip_name_lookup_own_resolve_address_stream_t) { *((int32_t*) (ptr + 4)) }; + break; + } + case 1: { + result.is_err = true; + result.val.err = (int32_t) *((uint8_t*) (ptr + 4)); + break; + } + } + if (!result.is_err) { + *ret = result.val.ok; + return 1; + } else { + *err = result.val.err; + return 0; + } +} + void random_get_random_bytes(uint64_t len, wasip2_list_u8_t *ret) { __attribute__((__aligned__(sizeof(void*)))) uint8_t ret_area[(2*sizeof(void*))]; diff --git a/libc-bottom-half/sources/wasip2_component_type.o b/libc-bottom-half/sources/wasip2_component_type.o index 92cccf9b4..abbd24294 100644 Binary files a/libc-bottom-half/sources/wasip2_component_type.o and b/libc-bottom-half/sources/wasip2_component_type.o differ diff --git a/libc-bottom-half/sources/wasip3.c b/libc-bottom-half/sources/wasip3.c index b58e84ded..f36937a32 100644 --- a/libc-bottom-half/sources/wasip3.c +++ b/libc-bottom-half/sources/wasip3.c @@ -1,304 +1,304 @@ -// Generated by `wit-bindgen` 0.48.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.51.0. DO NOT EDIT! #include "wasi/wasip3.h" #include #include -// Imported Functions from `wasi:cli/environment@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/environment@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2025-09-16"), __import_name__("get-environment"))) +__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2026-01-06"), __import_name__("get-environment"))) extern void __wasm_import_environment_get_environment(uint8_t *); -__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2025-09-16"), __import_name__("get-arguments"))) +__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2026-01-06"), __import_name__("get-arguments"))) extern void __wasm_import_environment_get_arguments(uint8_t *); -__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2025-09-16"), __import_name__("get-initial-cwd"))) +__attribute__((__import_module__("wasi:cli/environment@0.3.0-rc-2026-01-06"), __import_name__("get-initial-cwd"))) extern void __wasm_import_environment_get_initial_cwd(uint8_t *); -// Imported Functions from `wasi:cli/exit@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/exit@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/exit@0.3.0-rc-2025-09-16"), __import_name__("exit"))) +__attribute__((__import_module__("wasi:cli/exit@0.3.0-rc-2026-01-06"), __import_name__("exit"))) _Noreturn extern void __wasm_import_exit_exit(int32_t); -// Imported Functions from `wasi:cli/stdin@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stdin@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("read-via-stream"))) extern void __wasm_import_stdin_read_via_stream(uint8_t *); -// Imported Functions from `wasi:cli/stdout@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stdout@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/stdout@0.3.0-rc-2025-09-16"), __import_name__("[async-lower]write-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdout@0.3.0-rc-2026-01-06"), __import_name__("[async-lower]write-via-stream"))) extern int32_t __wasm_import_stdout_write_via_stream(int32_t, uint8_t *); -// Imported Functions from `wasi:cli/stderr@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/stderr@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/stderr@0.3.0-rc-2025-09-16"), __import_name__("[async-lower]write-via-stream"))) +__attribute__((__import_module__("wasi:cli/stderr@0.3.0-rc-2026-01-06"), __import_name__("[async-lower]write-via-stream"))) extern int32_t __wasm_import_stderr_write_via_stream(int32_t, uint8_t *); -// Imported Functions from `wasi:cli/terminal-stdin@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stdin@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/terminal-stdin@0.3.0-rc-2025-09-16"), __import_name__("get-terminal-stdin"))) +__attribute__((__import_module__("wasi:cli/terminal-stdin@0.3.0-rc-2026-01-06"), __import_name__("get-terminal-stdin"))) extern void __wasm_import_terminal_stdin_get_terminal_stdin(uint8_t *); -// Imported Functions from `wasi:cli/terminal-stdout@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stdout@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/terminal-stdout@0.3.0-rc-2025-09-16"), __import_name__("get-terminal-stdout"))) +__attribute__((__import_module__("wasi:cli/terminal-stdout@0.3.0-rc-2026-01-06"), __import_name__("get-terminal-stdout"))) extern void __wasm_import_terminal_stdout_get_terminal_stdout(uint8_t *); -// Imported Functions from `wasi:cli/terminal-stderr@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:cli/terminal-stderr@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:cli/terminal-stderr@0.3.0-rc-2025-09-16"), __import_name__("get-terminal-stderr"))) +__attribute__((__import_module__("wasi:cli/terminal-stderr@0.3.0-rc-2026-01-06"), __import_name__("get-terminal-stderr"))) extern void __wasm_import_terminal_stderr_get_terminal_stderr(uint8_t *); -// Imported Functions from `wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16"), __import_name__("now"))) +__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06"), __import_name__("now"))) extern int64_t __wasm_import_monotonic_clock_now(void); -__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16"), __import_name__("get-resolution"))) +__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06"), __import_name__("get-resolution"))) extern int64_t __wasm_import_monotonic_clock_get_resolution(void); -__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16"), __import_name__("[async-lower]wait-until"))) +__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06"), __import_name__("[async-lower]wait-until"))) extern int32_t __wasm_import_monotonic_clock_wait_until(int64_t); -__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2025-09-16"), __import_name__("[async-lower]wait-for"))) +__attribute__((__import_module__("wasi:clocks/monotonic-clock@0.3.0-rc-2026-01-06"), __import_name__("[async-lower]wait-for"))) extern int32_t __wasm_import_monotonic_clock_wait_for(int64_t); -// Imported Functions from `wasi:clocks/wall-clock@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:clocks/system-clock@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:clocks/wall-clock@0.3.0-rc-2025-09-16"), __import_name__("now"))) -extern void __wasm_import_wall_clock_now(uint8_t *); +__attribute__((__import_module__("wasi:clocks/system-clock@0.3.0-rc-2026-01-06"), __import_name__("now"))) +extern void __wasm_import_system_clock_now(uint8_t *); -__attribute__((__import_module__("wasi:clocks/wall-clock@0.3.0-rc-2025-09-16"), __import_name__("get-resolution"))) -extern void __wasm_import_wall_clock_get_resolution(uint8_t *); +__attribute__((__import_module__("wasi:clocks/system-clock@0.3.0-rc-2026-01-06"), __import_name__("get-resolution"))) +extern int64_t __wasm_import_system_clock_get_resolution(void); -// Imported Functions from `wasi:filesystem/types@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:filesystem/types@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[method]descriptor.read-via-stream"))) extern void __wasm_import_filesystem_method_descriptor_read_via_stream(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.write-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.write-via-stream"))) extern int32_t __wasm_import_filesystem_method_descriptor_write_via_stream(int32_t, int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.append-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.append-via-stream"))) extern int32_t __wasm_import_filesystem_method_descriptor_append_via_stream(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.advise"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.advise"))) extern int32_t __wasm_import_filesystem_method_descriptor_advise(int32_t, int64_t, int64_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.sync-data"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.sync-data"))) extern int32_t __wasm_import_filesystem_method_descriptor_sync_data(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.get-flags"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.get-flags"))) extern int32_t __wasm_import_filesystem_method_descriptor_get_flags(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.get-type"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.get-type"))) extern int32_t __wasm_import_filesystem_method_descriptor_get_type(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.set-size"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.set-size"))) extern int32_t __wasm_import_filesystem_method_descriptor_set_size(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.set-times"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.set-times"))) extern int32_t __wasm_import_filesystem_method_descriptor_set_times(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.read-directory"))) extern int32_t __wasm_import_filesystem_method_descriptor_read_directory(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.sync"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.sync"))) extern int32_t __wasm_import_filesystem_method_descriptor_sync(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.create-directory-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.create-directory-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_create_directory_at(int32_t, uint8_t *, size_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.stat"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.stat"))) extern int32_t __wasm_import_filesystem_method_descriptor_stat(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.stat-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.stat-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_stat_at(int32_t, int32_t, uint8_t *, size_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.set-times-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.set-times-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_set_times_at(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.link-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.link-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_link_at(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.open-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.open-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_open_at(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.readlink-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.readlink-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_readlink_at(int32_t, uint8_t *, size_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.remove-directory-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.remove-directory-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_remove_directory_at(int32_t, uint8_t *, size_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.rename-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.rename-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_rename_at(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.symlink-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.symlink-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_symlink_at(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.unlink-file-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.unlink-file-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_unlink_file_at(int32_t, uint8_t *, size_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.is-same-object"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.is-same-object"))) extern int32_t __wasm_import_filesystem_method_descriptor_is_same_object(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.metadata-hash"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.metadata-hash"))) extern int32_t __wasm_import_filesystem_method_descriptor_metadata_hash(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]descriptor.metadata-hash-at"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]descriptor.metadata-hash-at"))) extern int32_t __wasm_import_filesystem_method_descriptor_metadata_hash_at(int32_t, int32_t, uint8_t *, size_t, uint8_t *); -// Imported Functions from `wasi:filesystem/preopens@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:filesystem/preopens@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:filesystem/preopens@0.3.0-rc-2025-09-16"), __import_name__("get-directories"))) +__attribute__((__import_module__("wasi:filesystem/preopens@0.3.0-rc-2026-01-06"), __import_name__("get-directories"))) extern void __wasm_import_filesystem_preopens_get_directories(uint8_t *); -// Imported Functions from `wasi:sockets/types@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:sockets/types@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[static]tcp-socket.create"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[static]tcp-socket.create"))) extern void __wasm_import_sockets_static_tcp_socket_create(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.bind"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.bind"))) extern void __wasm_import_sockets_method_tcp_socket_bind(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]tcp-socket.connect"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]tcp-socket.connect"))) extern int32_t __wasm_import_sockets_method_tcp_socket_connect(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.listen"))) extern void __wasm_import_sockets_method_tcp_socket_listen(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]tcp-socket.send"))) extern int32_t __wasm_import_sockets_method_tcp_socket_send(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.receive"))) extern void __wasm_import_sockets_method_tcp_socket_receive(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-local-address"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-local-address"))) extern void __wasm_import_sockets_method_tcp_socket_get_local_address(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-remote-address"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-remote-address"))) extern void __wasm_import_sockets_method_tcp_socket_get_remote_address(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-is-listening"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-is-listening"))) extern int32_t __wasm_import_sockets_method_tcp_socket_get_is_listening(int32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-address-family"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-address-family"))) extern int32_t __wasm_import_sockets_method_tcp_socket_get_address_family(int32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-listen-backlog-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-listen-backlog-size"))) extern void __wasm_import_sockets_method_tcp_socket_set_listen_backlog_size(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-keep-alive-enabled"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-keep-alive-enabled"))) extern void __wasm_import_sockets_method_tcp_socket_get_keep_alive_enabled(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-keep-alive-enabled"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-keep-alive-enabled"))) extern void __wasm_import_sockets_method_tcp_socket_set_keep_alive_enabled(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-keep-alive-idle-time"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-keep-alive-idle-time"))) extern void __wasm_import_sockets_method_tcp_socket_get_keep_alive_idle_time(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-keep-alive-idle-time"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-keep-alive-idle-time"))) extern void __wasm_import_sockets_method_tcp_socket_set_keep_alive_idle_time(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-keep-alive-interval"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-keep-alive-interval"))) extern void __wasm_import_sockets_method_tcp_socket_get_keep_alive_interval(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-keep-alive-interval"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-keep-alive-interval"))) extern void __wasm_import_sockets_method_tcp_socket_set_keep_alive_interval(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-keep-alive-count"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-keep-alive-count"))) extern void __wasm_import_sockets_method_tcp_socket_get_keep_alive_count(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-keep-alive-count"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-keep-alive-count"))) extern void __wasm_import_sockets_method_tcp_socket_set_keep_alive_count(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-hop-limit"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-hop-limit"))) extern void __wasm_import_sockets_method_tcp_socket_get_hop_limit(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-hop-limit"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-hop-limit"))) extern void __wasm_import_sockets_method_tcp_socket_set_hop_limit(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-receive-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-receive-buffer-size"))) extern void __wasm_import_sockets_method_tcp_socket_get_receive_buffer_size(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-receive-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-receive-buffer-size"))) extern void __wasm_import_sockets_method_tcp_socket_set_receive_buffer_size(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.get-send-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.get-send-buffer-size"))) extern void __wasm_import_sockets_method_tcp_socket_get_send_buffer_size(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]tcp-socket.set-send-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]tcp-socket.set-send-buffer-size"))) extern void __wasm_import_sockets_method_tcp_socket_set_send_buffer_size(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[static]udp-socket.create"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[static]udp-socket.create"))) extern void __wasm_import_sockets_static_udp_socket_create(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.bind"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.bind"))) extern void __wasm_import_sockets_method_udp_socket_bind(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.connect"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.connect"))) extern void __wasm_import_sockets_method_udp_socket_connect(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.disconnect"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.disconnect"))) extern void __wasm_import_sockets_method_udp_socket_disconnect(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]udp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]udp-socket.send"))) extern int32_t __wasm_import_sockets_method_udp_socket_send(uint8_t *, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][method]udp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][method]udp-socket.receive"))) extern int32_t __wasm_import_sockets_method_udp_socket_receive(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-local-address"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-local-address"))) extern void __wasm_import_sockets_method_udp_socket_get_local_address(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-remote-address"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-remote-address"))) extern void __wasm_import_sockets_method_udp_socket_get_remote_address(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-address-family"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-address-family"))) extern int32_t __wasm_import_sockets_method_udp_socket_get_address_family(int32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-unicast-hop-limit"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-unicast-hop-limit"))) extern void __wasm_import_sockets_method_udp_socket_get_unicast_hop_limit(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.set-unicast-hop-limit"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.set-unicast-hop-limit"))) extern void __wasm_import_sockets_method_udp_socket_set_unicast_hop_limit(int32_t, int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-receive-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-receive-buffer-size"))) extern void __wasm_import_sockets_method_udp_socket_get_receive_buffer_size(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.set-receive-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.set-receive-buffer-size"))) extern void __wasm_import_sockets_method_udp_socket_set_receive_buffer_size(int32_t, int64_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.get-send-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.get-send-buffer-size"))) extern void __wasm_import_sockets_method_udp_socket_get_send_buffer_size(int32_t, uint8_t *); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[method]udp-socket.set-send-buffer-size"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[method]udp-socket.set-send-buffer-size"))) extern void __wasm_import_sockets_method_udp_socket_set_send_buffer_size(int32_t, int64_t, uint8_t *); -// Imported Functions from `wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.3.0-rc-2025-09-16"), __import_name__("[async-lower]resolve-addresses"))) +__attribute__((__import_module__("wasi:sockets/ip-name-lookup@0.3.0-rc-2026-01-06"), __import_name__("[async-lower]resolve-addresses"))) extern int32_t __wasm_import_ip_name_lookup_resolve_addresses(uint8_t *, size_t, uint8_t *); -// Imported Functions from `wasi:random/random@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/random@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:random/random@0.3.0-rc-2025-09-16"), __import_name__("get-random-bytes"))) +__attribute__((__import_module__("wasi:random/random@0.3.0-rc-2026-01-06"), __import_name__("get-random-bytes"))) extern void __wasm_import_random_get_random_bytes(int64_t, uint8_t *); -__attribute__((__import_module__("wasi:random/random@0.3.0-rc-2025-09-16"), __import_name__("get-random-u64"))) +__attribute__((__import_module__("wasi:random/random@0.3.0-rc-2026-01-06"), __import_name__("get-random-u64"))) extern int64_t __wasm_import_random_get_random_u64(void); -// Imported Functions from `wasi:random/insecure@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/insecure@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:random/insecure@0.3.0-rc-2025-09-16"), __import_name__("get-insecure-random-bytes"))) +__attribute__((__import_module__("wasi:random/insecure@0.3.0-rc-2026-01-06"), __import_name__("get-insecure-random-bytes"))) extern void __wasm_import_random_insecure_get_insecure_random_bytes(int64_t, uint8_t *); -__attribute__((__import_module__("wasi:random/insecure@0.3.0-rc-2025-09-16"), __import_name__("get-insecure-random-u64"))) +__attribute__((__import_module__("wasi:random/insecure@0.3.0-rc-2026-01-06"), __import_name__("get-insecure-random-u64"))) extern int64_t __wasm_import_random_insecure_get_insecure_random_u64(void); -// Imported Functions from `wasi:random/insecure-seed@0.3.0-rc-2025-09-16` +// Imported Functions from `wasi:random/insecure-seed@0.3.0-rc-2026-01-06` -__attribute__((__import_module__("wasi:random/insecure-seed@0.3.0-rc-2025-09-16"), __import_name__("get-insecure-seed"))) +__attribute__((__import_module__("wasi:random/insecure-seed@0.3.0-rc-2026-01-06"), __import_name__("get-insecure-seed"))) extern void __wasm_import_random_insecure_seed_get_insecure_seed(uint8_t *); // Canonical ABI intrinsics @@ -358,19 +358,19 @@ void stdin_result_void_error_code_free(stdin_result_void_error_code_t *ptr) { } } -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[stream-new-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[stream-new-0]read-via-stream"))) extern uint64_t stdin_stream_u8__new(void); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-read-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-read-0]read-via-stream"))) extern uint32_t stdin_stream_u8__read(uint32_t, uint8_t*, size_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-write-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-write-0]read-via-stream"))) extern uint32_t stdin_stream_u8__write(uint32_t, const uint8_t*, size_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-read-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-read-0]read-via-stream"))) extern uint32_t stdin_stream_u8__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-write-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-write-0]read-via-stream"))) extern uint32_t stdin_stream_u8__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-readable-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-readable-0]read-via-stream"))) extern void stdin_stream_u8__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-writable-0]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-writable-0]read-via-stream"))) extern void stdin_stream_u8__drop_writable(uint32_t); stdin_stream_u8_t stdin_stream_u8_new(stdin_stream_u8_writer_t *writer) { @@ -404,19 +404,19 @@ void stdin_stream_u8_drop_writable(stdin_stream_u8_writer_t writer) { } -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[future-new-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[future-new-1]read-via-stream"))) extern uint64_t stdin_future_result_void_error_code__new(void); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-read-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-read-1]read-via-stream"))) extern uint32_t stdin_future_result_void_error_code__read(uint32_t, uint8_t*); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-write-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-write-1]read-via-stream"))) extern uint32_t stdin_future_result_void_error_code__write(uint32_t, const uint8_t*); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-read-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-read-1]read-via-stream"))) extern uint32_t stdin_future_result_void_error_code__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-write-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-write-1]read-via-stream"))) extern uint32_t stdin_future_result_void_error_code__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-readable-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-readable-1]read-via-stream"))) extern void stdin_future_result_void_error_code__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-writable-1]read-via-stream"))) +__attribute__((__import_module__("wasi:cli/stdin@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-writable-1]read-via-stream"))) extern void stdin_future_result_void_error_code__drop_writable(uint32_t); stdin_future_result_void_error_code_t stdin_future_result_void_error_code_new(stdin_future_result_void_error_code_writer_t *writer) { @@ -462,7 +462,7 @@ void stderr_result_void_error_code_free(stderr_result_void_error_code_t *ptr) { } } -__attribute__((__import_module__("wasi:cli/terminal-input@0.3.0-rc-2025-09-16"), __import_name__("[resource-drop]terminal-input"))) +__attribute__((__import_module__("wasi:cli/terminal-input@0.3.0-rc-2026-01-06"), __import_name__("[resource-drop]terminal-input"))) extern void __wasm_import_terminal_input_terminal_input_drop(int32_t handle); void terminal_input_terminal_input_drop_own(terminal_input_own_terminal_input_t handle) { @@ -473,7 +473,7 @@ terminal_input_borrow_terminal_input_t terminal_input_borrow_terminal_input(term return (terminal_input_borrow_terminal_input_t) { arg.__handle }; } -__attribute__((__import_module__("wasi:cli/terminal-output@0.3.0-rc-2025-09-16"), __import_name__("[resource-drop]terminal-output"))) +__attribute__((__import_module__("wasi:cli/terminal-output@0.3.0-rc-2026-01-06"), __import_name__("[resource-drop]terminal-output"))) extern void __wasm_import_terminal_output_terminal_output_drop(int32_t handle); void terminal_output_terminal_output_drop_own(terminal_output_own_terminal_output_t handle) { @@ -499,15 +499,15 @@ void terminal_stderr_option_own_terminal_output_free(terminal_stderr_option_own_ } } -void filesystem_option_datetime_free(filesystem_option_datetime_t *ptr) { +void filesystem_option_instant_free(filesystem_option_instant_t *ptr) { if (ptr->is_some) { } } void filesystem_descriptor_stat_free(filesystem_descriptor_stat_t *ptr) { - filesystem_option_datetime_free(&ptr->data_access_timestamp); - filesystem_option_datetime_free(&ptr->data_modification_timestamp); - filesystem_option_datetime_free(&ptr->status_change_timestamp); + filesystem_option_instant_free(&ptr->data_access_timestamp); + filesystem_option_instant_free(&ptr->data_modification_timestamp); + filesystem_option_instant_free(&ptr->status_change_timestamp); } void filesystem_new_timestamp_free(filesystem_new_timestamp_t *ptr) { @@ -522,7 +522,7 @@ void filesystem_directory_entry_free(filesystem_directory_entry_t *ptr) { wasip3_string_free(&ptr->name); } -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[resource-drop]descriptor"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[resource-drop]descriptor"))) extern void __wasm_import_filesystem_descriptor_drop(int32_t handle); void filesystem_descriptor_drop_own(filesystem_own_descriptor_t handle) { @@ -577,19 +577,19 @@ void filesystem_result_metadata_hash_value_error_code_free(filesystem_result_met } } -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-new-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-new-0][method]descriptor.read-via-stream"))) extern uint64_t filesystem_stream_u8__new(void); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-read-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-read-0][method]descriptor.read-via-stream"))) extern uint32_t filesystem_stream_u8__read(uint32_t, uint8_t*, size_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-write-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-write-0][method]descriptor.read-via-stream"))) extern uint32_t filesystem_stream_u8__write(uint32_t, const uint8_t*, size_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-read-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-read-0][method]descriptor.read-via-stream"))) extern uint32_t filesystem_stream_u8__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-write-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-write-0][method]descriptor.read-via-stream"))) extern uint32_t filesystem_stream_u8__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-readable-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-readable-0][method]descriptor.read-via-stream"))) extern void filesystem_stream_u8__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-writable-0][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-writable-0][method]descriptor.read-via-stream"))) extern void filesystem_stream_u8__drop_writable(uint32_t); filesystem_stream_u8_t filesystem_stream_u8_new(filesystem_stream_u8_writer_t *writer) { @@ -623,19 +623,19 @@ void filesystem_stream_u8_drop_writable(filesystem_stream_u8_writer_t writer) { } -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[future-new-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[future-new-1][method]descriptor.read-via-stream"))) extern uint64_t filesystem_future_result_void_error_code__new(void); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-read-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-read-1][method]descriptor.read-via-stream"))) extern uint32_t filesystem_future_result_void_error_code__read(uint32_t, uint8_t*); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-write-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-write-1][method]descriptor.read-via-stream"))) extern uint32_t filesystem_future_result_void_error_code__write(uint32_t, const uint8_t*); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-read-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-read-1][method]descriptor.read-via-stream"))) extern uint32_t filesystem_future_result_void_error_code__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-write-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-write-1][method]descriptor.read-via-stream"))) extern uint32_t filesystem_future_result_void_error_code__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-readable-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-readable-1][method]descriptor.read-via-stream"))) extern void filesystem_future_result_void_error_code__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-writable-1][method]descriptor.read-via-stream"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-writable-1][method]descriptor.read-via-stream"))) extern void filesystem_future_result_void_error_code__drop_writable(uint32_t); filesystem_future_result_void_error_code_t filesystem_future_result_void_error_code_new(filesystem_future_result_void_error_code_writer_t *writer) { @@ -669,19 +669,19 @@ void filesystem_future_result_void_error_code_drop_writable(filesystem_future_re } -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-new-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-new-0][method]descriptor.read-directory"))) extern uint64_t filesystem_stream_directory_entry__new(void); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-read-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-read-0][method]descriptor.read-directory"))) extern uint32_t filesystem_stream_directory_entry__read(uint32_t, uint8_t*, size_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-write-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-write-0][method]descriptor.read-directory"))) extern uint32_t filesystem_stream_directory_entry__write(uint32_t, const uint8_t*, size_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-read-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-read-0][method]descriptor.read-directory"))) extern uint32_t filesystem_stream_directory_entry__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-write-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-write-0][method]descriptor.read-directory"))) extern uint32_t filesystem_stream_directory_entry__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-readable-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-readable-0][method]descriptor.read-directory"))) extern void filesystem_stream_directory_entry__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-writable-0][method]descriptor.read-directory"))) +__attribute__((__import_module__("wasi:filesystem/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-writable-0][method]descriptor.read-directory"))) extern void filesystem_stream_directory_entry__drop_writable(uint32_t); filesystem_stream_directory_entry_t filesystem_stream_directory_entry_new(filesystem_stream_directory_entry_writer_t *writer) { @@ -752,7 +752,7 @@ void sockets_ip_socket_address_free(sockets_ip_socket_address_t *ptr) { } } -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[resource-drop]tcp-socket"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[resource-drop]tcp-socket"))) extern void __wasm_import_sockets_tcp_socket_drop(int32_t handle); void sockets_tcp_socket_drop_own(sockets_own_tcp_socket_t handle) { @@ -763,7 +763,7 @@ sockets_borrow_tcp_socket_t sockets_borrow_tcp_socket(sockets_own_tcp_socket_t a return (sockets_borrow_tcp_socket_t) { arg.__handle }; } -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[resource-drop]udp-socket"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[resource-drop]udp-socket"))) extern void __wasm_import_sockets_udp_socket_drop(int32_t handle); void sockets_udp_socket_drop_own(sockets_own_udp_socket_t handle) { @@ -863,19 +863,19 @@ void sockets_result_tuple2_list_u8_ip_socket_address_error_code_free(sockets_res } } -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-new-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-new-0][method]tcp-socket.listen"))) extern uint64_t sockets_stream_own_tcp_socket__new(void); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-read-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-read-0][method]tcp-socket.listen"))) extern uint32_t sockets_stream_own_tcp_socket__read(uint32_t, uint8_t*, size_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-write-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-write-0][method]tcp-socket.listen"))) extern uint32_t sockets_stream_own_tcp_socket__write(uint32_t, const uint8_t*, size_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-read-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-read-0][method]tcp-socket.listen"))) extern uint32_t sockets_stream_own_tcp_socket__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-write-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-write-0][method]tcp-socket.listen"))) extern uint32_t sockets_stream_own_tcp_socket__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-readable-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-readable-0][method]tcp-socket.listen"))) extern void sockets_stream_own_tcp_socket__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-writable-0][method]tcp-socket.listen"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-writable-0][method]tcp-socket.listen"))) extern void sockets_stream_own_tcp_socket__drop_writable(uint32_t); sockets_stream_own_tcp_socket_t sockets_stream_own_tcp_socket_new(sockets_stream_own_tcp_socket_writer_t *writer) { @@ -909,19 +909,19 @@ void sockets_stream_own_tcp_socket_drop_writable(sockets_stream_own_tcp_socket_w } -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-new-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-new-0][method]tcp-socket.send"))) extern uint64_t sockets_stream_u8__new(void); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-read-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-read-0][method]tcp-socket.send"))) extern uint32_t sockets_stream_u8__read(uint32_t, uint8_t*, size_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][stream-write-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][stream-write-0][method]tcp-socket.send"))) extern uint32_t sockets_stream_u8__write(uint32_t, const uint8_t*, size_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-read-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-read-0][method]tcp-socket.send"))) extern uint32_t sockets_stream_u8__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-cancel-write-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-cancel-write-0][method]tcp-socket.send"))) extern uint32_t sockets_stream_u8__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-readable-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-readable-0][method]tcp-socket.send"))) extern void sockets_stream_u8__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[stream-drop-writable-0][method]tcp-socket.send"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[stream-drop-writable-0][method]tcp-socket.send"))) extern void sockets_stream_u8__drop_writable(uint32_t); sockets_stream_u8_t sockets_stream_u8_new(sockets_stream_u8_writer_t *writer) { @@ -955,19 +955,19 @@ void sockets_stream_u8_drop_writable(sockets_stream_u8_writer_t writer) { } -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[future-new-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[future-new-1][method]tcp-socket.receive"))) extern uint64_t sockets_future_result_void_error_code__new(void); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-read-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-read-1][method]tcp-socket.receive"))) extern uint32_t sockets_future_result_void_error_code__read(uint32_t, uint8_t*); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[async-lower][future-write-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[async-lower][future-write-1][method]tcp-socket.receive"))) extern uint32_t sockets_future_result_void_error_code__write(uint32_t, const uint8_t*); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-read-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-read-1][method]tcp-socket.receive"))) extern uint32_t sockets_future_result_void_error_code__cancel_read(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[future-cancel-write-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[future-cancel-write-1][method]tcp-socket.receive"))) extern uint32_t sockets_future_result_void_error_code__cancel_write(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-readable-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-readable-1][method]tcp-socket.receive"))) extern void sockets_future_result_void_error_code__drop_readable(uint32_t); -__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2025-09-16"), __import_name__("[future-drop-writable-1][method]tcp-socket.receive"))) +__attribute__((__import_module__("wasi:sockets/types@0.3.0-rc-2026-01-06"), __import_name__("[future-drop-writable-1][method]tcp-socket.receive"))) extern void sockets_future_result_void_error_code__drop_writable(uint32_t); sockets_future_result_void_error_code_t sockets_future_result_void_error_code_new(sockets_future_result_void_error_code_writer_t *writer) { @@ -1034,6 +1034,12 @@ void wasip3_string_dup(wasip3_string_t *ret, const char*s) { memcpy(ret->ptr, s, ret->len * 1); } +void wasip3_string_dup_n(wasip3_string_t *ret, const char*s, size_t len) { + ret->len = len; + ret->ptr = (uint8_t*) cabi_realloc(NULL, 0, 1, ret->len * 1); + memcpy(ret->ptr, s, ret->len * 1); +} + void wasip3_string_free(wasip3_string_t *ret) { if (ret->len > 0) { free(ret->ptr); @@ -1099,13 +1105,6 @@ void wasip3_task_cancel() { __task_cancel(); } -__attribute__((__import_module__("$root"), __import_name__("[backpressure-set]"))) -extern void __backpressure_set(bool enable); - -void wasip3_backpressure_set(bool enable) { - __backpressure_set(enable); -} - __attribute__((__import_module__("$root"), __import_name__("[backpressure-inc]"))) extern void __backpressure_inc(void); @@ -1121,33 +1120,112 @@ void wasip3_backpressure_dec(void) { } __attribute__((__import_module__("$root"), __import_name__("[context-get-0]"))) -extern void* __context_get(void); +extern void* __context_get_0(void); -void* wasip3_context_get() { - return __context_get(); +void* wasip3_context_get_0(void) { + return __context_get_0(); } __attribute__((__import_module__("$root"), __import_name__("[context-set-0]"))) -extern void __context_set(void*); +extern void __context_set_0(void*); -void wasip3_context_set(void *val) { - return __context_set(val); + +void wasip3_context_set_0(void *value) { + __context_set_0(value); } __attribute__((__import_module__("$root"), __import_name__("[thread-yield]"))) extern uint32_t __thread_yield(void); -void wasip3_yield(void) { +void wasip3_thread_yield(void) { __thread_yield(); } + +__attribute__((__import_module__("$root"), __import_name__("[context-get-1]"))) +extern void* __context_get_1(void); + +void* wasip3_context_get_1(void) { + return __context_get_1(); +} + +__attribute__((__import_module__("$root"), __import_name__("[context-set-1]"))) +extern void __context_set_1(void*); + +void wasip3_context_set_1(void* value) { + __context_set_1(value); +} + __attribute__((__import_module__("$root"), __import_name__("[cancellable][thread-yield]"))) extern uint32_t __thread_yield_cancellable(void); -uint32_t wasip3_yield_cancellable(void) { +uint32_t wasip3_thread_yield_cancellable(void) { return __thread_yield_cancellable(); } +__attribute__((__import_module__("$root"), __import_name__("[thread-index]"))) +extern uint32_t __thread_index(void); + +uint32_t wasip3_thread_index(void) { + return __thread_index(); +} + +__attribute__((__import_module__("$root"), __import_name__("[thread-new-indirect-v0]"))) +extern uint32_t __thread_new_indirect(uint32_t, void*); + +uint32_t wasip3_thread_new_indirect(void (*start_function)(void*), void* arg) { + return __thread_new_indirect((uint32_t)(uintptr_t)start_function, arg + ); +} + +__attribute__((__import_module__("$root"), __import_name__("[thread-switch-to]"))) +extern uint32_t __thread_switch_to(uint32_t); + +void wasip3_thread_switch_to(uint32_t thread) { + __thread_switch_to(thread); +} + +__attribute__((__import_module__("$root"), __import_name__("[cancellable][thread-switch-to]"))) +extern uint32_t __thread_switch_to_cancellable(uint32_t); + +uint32_t wasip3_thread_switch_to_cancellable(uint32_t thread) { + return __thread_switch_to_cancellable(thread); +} + +__attribute__((__import_module__("$root"), __import_name__("[thread-resume-later]"))) +extern void __thread_resume_later(uint32_t); + +void wasip3_thread_resume_later(uint32_t thread) { + __thread_resume_later(thread); +} + +__attribute__((__import_module__("$root"), __import_name__("[thread-yield-to]"))) +extern uint32_t __thread_yield_to(uint32_t); + +void wasip3_thread_yield_to(uint32_t thread) { + __thread_yield_to(thread); +} + +__attribute__((__import_module__("$root"), __import_name__("[cancellable][thread-yield-to]"))) +extern uint32_t __thread_yield_to_cancellable(uint32_t); + +uint32_t wasip3_thread_yield_to_cancellable(uint32_t thread) { + return __thread_yield_to_cancellable(thread); +} + +__attribute__((__import_module__("$root"), __import_name__("[thread-suspend]"))) +extern uint32_t __thread_suspend(void); + +void wasip3_thread_suspend(void) { + __thread_suspend(); +} + +__attribute__((__import_module__("$root"), __import_name__("[cancellable][thread-suspend]"))) +extern uint32_t __thread_suspend_cancellable(void); +uint32_t wasip3_thread_suspend_cancellable(void) { + return __thread_suspend_cancellable(); +} + // Component Adapters @@ -1281,7 +1359,7 @@ bool terminal_stderr_get_terminal_stderr(terminal_stderr_own_terminal_output_t * return option.is_some; } -monotonic_clock_instant_t monotonic_clock_now(void) { +monotonic_clock_mark_t monotonic_clock_now(void) { int64_t ret = __wasm_import_monotonic_clock_now(); return (uint64_t) (ret); } @@ -1291,7 +1369,7 @@ monotonic_clock_duration_t monotonic_clock_get_resolution(void) { return (uint64_t) (ret); } -wasip3_subtask_status_t monotonic_clock_wait_until(monotonic_clock_instant_t when) { +wasip3_subtask_status_t monotonic_clock_wait_until(monotonic_clock_mark_t when) { return __wasm_import_monotonic_clock_wait_until((int64_t) (when)); } @@ -1299,26 +1377,20 @@ wasip3_subtask_status_t monotonic_clock_wait_for(monotonic_clock_duration_t how_ return __wasm_import_monotonic_clock_wait_for((int64_t) (how_long)); } -void wall_clock_now(wall_clock_datetime_t *ret) { +void system_clock_now(system_clock_instant_t *ret) { __attribute__((__aligned__(8))) uint8_t ret_area[16]; uint8_t *ptr = (uint8_t *) &ret_area; - __wasm_import_wall_clock_now(ptr); - *ret = (wall_clock_datetime_t) { - (uint64_t) (uint64_t) (*((int64_t*) (ptr + 0))), + __wasm_import_system_clock_now(ptr); + *ret = (system_clock_instant_t) { + (int64_t) *((int64_t*) (ptr + 0)), (uint32_t) (uint32_t) (*((int32_t*) (ptr + 8))), }; } -void wall_clock_get_resolution(wall_clock_datetime_t *ret) { - __attribute__((__aligned__(8))) - uint8_t ret_area[16]; - uint8_t *ptr = (uint8_t *) &ret_area; - __wasm_import_wall_clock_get_resolution(ptr); - *ret = (wall_clock_datetime_t) { - (uint64_t) (uint64_t) (*((int64_t*) (ptr + 0))), - (uint32_t) (uint32_t) (*((int32_t*) (ptr + 8))), - }; +system_clock_duration_t system_clock_get_resolution(void) { + int64_t ret = __wasm_import_system_clock_get_resolution(); + return (uint64_t) (ret); } void filesystem_method_descriptor_read_via_stream(filesystem_borrow_descriptor_t self, filesystem_filesize_t offset, filesystem_tuple2_stream_u8_future_result_void_error_code_t *ret) { diff --git a/libc-bottom-half/sources/wasip3_component_type.o b/libc-bottom-half/sources/wasip3_component_type.o index 2134f29a5..68f4f3604 100644 Binary files a/libc-bottom-half/sources/wasip3_component_type.o and b/libc-bottom-half/sources/wasip3_component_type.o differ diff --git a/libc-top-half/CMakeLists.txt b/libc-top-half/CMakeLists.txt index 8dcf63abc..1add546b0 100644 --- a/libc-top-half/CMakeLists.txt +++ b/libc-top-half/CMakeLists.txt @@ -389,7 +389,7 @@ if (NOT (WASI STREQUAL "p1")) ) endif() -if (THREADS) +if (THREADS OR (WASI STREQUAL "p3")) # pthreads functions needed for actual thread support list(APPEND top_half_sources musl/src/stdio/__lockfile.c @@ -435,9 +435,15 @@ if (THREADS) musl/src/thread/sem_timedwait.c musl/src/thread/sem_trywait.c musl/src/thread/sem_wait.c - musl/src/thread/wasm32/wasi_thread_start.s musl/src/thread/wasm32/__wasilibc_busywait.c ) + if (THREADS) + list (APPEND top_half_sources + musl/src/thread/wasm32/wasi_thread_start.s) + elseif(WASI STREQUAL "p3") + list (APPEND top_half_sources + musl/src/thread/wasm32/wasip3_thread_start.s) + endif() else() # pthreads stubs for single-threaded environment list(APPEND top_half_sources diff --git a/libc-top-half/musl/src/env/__init_tls.c b/libc-top-half/musl/src/env/__init_tls.c index 7f0d92931..10566f5c6 100644 --- a/libc-top-half/musl/src/env/__init_tls.c +++ b/libc-top-half/musl/src/env/__init_tls.c @@ -6,6 +6,7 @@ #ifdef __wasilibc_unmodified_upstream #include #endif +#include #include #include #include "pthread_impl.h" @@ -40,6 +41,26 @@ struct stack_bounds { size_t size; }; +static inline unsigned char *get_stack_pointer() { + unsigned char *sp; +#ifdef __wasip3__ + __asm__( + ".functype __wasm_component_model_builtin_context_get_0 () -> (i32)\n" + ".import_module __wasm_component_model_builtin_context_get_0, \"$root\"\n" + ".import_name __wasm_component_model_builtin_context_get_0, \"[context-get-0]\"\n" + "call __wasm_component_model_builtin_context_get_0\n" + "local.set %0\n" + : "=r"(sp)); +#else + __asm__( + ".globaltype __stack_pointer, i32\n" + "global.get __stack_pointer\n" + "local.set %0\n" + : "=r"(sp)); +#endif + return sp; +} + static inline struct stack_bounds get_stack_bounds() { struct stack_bounds bounds; @@ -52,12 +73,7 @@ static inline struct stack_bounds get_stack_bounds() * how wasm-ld lays out things. For pic, just give up. */ #if !defined(__pic__) - unsigned char *sp; - __asm__( - ".globaltype __stack_pointer, i32\n" - "global.get __stack_pointer\n" - "local.set %0\n" - : "=r"(sp)); + unsigned char *sp = get_stack_pointer(); if (sp > &__global_base) { bounds.base = &__heap_base; bounds.size = &__heap_base - &__data_end; @@ -97,7 +113,10 @@ int __init_tp(void *p) td->stack = bounds.base; td->stack_size = bounds.size; td->guard_size = 0; -#ifdef _REENTRANT +#if defined(__wasip3__) + td->detach_state = DT_JOINABLE; + td->tid = wasip3_thread_index(); +#elif defined(_REENTRANT) td->detach_state = DT_JOINABLE; /* * Initialize the TID to a value which doesn't conflict with @@ -174,13 +193,15 @@ void *__copy_tls(unsigned char *mem) return td; #else size_t tls_align = __builtin_wasm_tls_align(); - volatile void* tls_base = __builtin_wasm_tls_base(); mem += tls_align; mem -= (uintptr_t)mem & (tls_align-1); __wasm_init_tls(mem); - __asm__("local.get %0\n" - "global.set __tls_base\n" - :: "r"(tls_base)); +#ifndef __wasip3__ + volatile void *tls_base = __builtin_wasm_tls_base(); + __asm__("local.get %0\n" + "global.set __tls_base\n" + ::"r"(tls_base)); +#endif return mem; #endif } diff --git a/libc-top-half/musl/src/internal/pthread_impl.h b/libc-top-half/musl/src/internal/pthread_impl.h index 0106ac385..6c70becb2 100644 --- a/libc-top-half/musl/src/internal/pthread_impl.h +++ b/libc-top-half/musl/src/internal/pthread_impl.h @@ -17,6 +17,8 @@ #include "atomic.h" #include "futex.h" +#include + #include "pthread_arch.h" #define pthread __pthread @@ -66,6 +68,9 @@ struct pthread { volatile int killlock[1]; char *dlerror_buf; void *stdio_locks; + #ifdef __wasip3__ + int joining_tid; + #endif /* Part 3 -- the positions of these fields relative to * the end of the structure is external and internal ABI. */ diff --git a/libc-top-half/musl/src/thread/pthread_create.c b/libc-top-half/musl/src/thread/pthread_create.c index 879b48c1f..45862575f 100644 --- a/libc-top-half/musl/src/thread/pthread_create.c +++ b/libc-top-half/musl/src/thread/pthread_create.c @@ -35,7 +35,8 @@ void __tl_lock(void) { int tid = __pthread_self()->tid; int val = __thread_list_lock; - if (val == tid) { + if (val == tid) + { tl_lock_count++; return; } @@ -45,21 +46,25 @@ void __tl_lock(void) void __tl_unlock(void) { - if (tl_lock_count) { + if (tl_lock_count) + { tl_lock_count--; return; } a_store(&__thread_list_lock, 0); - if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); + if (tl_lock_waiters) + __wake(&__thread_list_lock, 1, 0); } void __tl_sync(pthread_t td) { a_barrier(); int val = __thread_list_lock; - if (!val) return; + if (!val) + return; __wait(&__thread_list_lock, &tl_lock_waiters, val, 0); - if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); + if (tl_lock_waiters) + __wake(&__thread_list_lock, 1, 0); } #ifndef __wasilibc_unmodified_upstream @@ -86,7 +91,8 @@ static void __pthread_exit(void *result) self->cancelasync = 0; self->result = result; - while (self->cancelbuf) { + while (self->cancelbuf) + { void (*f)(void *) = self->cancelbuf->__f; void *x = self->cancelbuf->__x; self->cancelbuf = self->cancelbuf->__next; @@ -103,7 +109,8 @@ static void __pthread_exit(void *result) * call; the loser is responsible for freeing thread resources. */ int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING); - if (state==DT_DETACHED && self->map_base) { + if (state == DT_DETACHED && self->map_base) + { /* Since __unmapself bypasses the normal munmap code path, * explicitly wait for vmlock holders first. This must be * done before any locks are taken, to avoid lock ordering @@ -127,7 +134,8 @@ static void __pthread_exit(void *result) /* If this is the only thread in the list, don't proceed with * termination of the thread, but restore the previous lock and * signal state to prepare for exit to call atexit handlers. */ - if (self->next == self) { + if (self->next == self) + { __tl_unlock(); UNLOCK(self->killlock); self->detach_state = state; @@ -156,9 +164,9 @@ static void __pthread_exit(void *result) __vm_lock(); #endif volatile void *volatile *rp; - while ((rp=self->robust_list.head) && rp != &self->robust_list.head) { - pthread_mutex_t *m = (void *)((char *)rp - - offsetof(pthread_mutex_t, _m_next)); + while ((rp = self->robust_list.head) && rp != &self->robust_list.head) + { + pthread_mutex_t *m = (void *)((char *)rp - offsetof(pthread_mutex_t, _m_next)); int waiters = m->_m_waiters; int priv = (m->_m_type & 128) ^ 128; self->robust_list.pending = rp; @@ -182,13 +190,15 @@ static void __pthread_exit(void *result) * has been called, via the exit futex address pointing at the lock. * This needs to happen after any possible calls to LOCK() that might * skip locking if process appears single-threaded. */ - if (!--libc.threads_minus_1) libc.need_locks = -1; + if (!--libc.threads_minus_1) + libc.need_locks = -1; self->next->prev = self->prev; self->prev->next = self->next; self->prev = self->next = self; #ifdef __wasilibc_unmodified_upstream - if (state==DT_DETACHED && self->map_base) { + if (state == DT_DETACHED && self->map_base) + { /* Detached threads must block even implementation-internal * signals, since they will not have a stack in their last * moments of existence. */ @@ -197,14 +207,15 @@ static void __pthread_exit(void *result) /* Robust list will no longer be valid, and was already * processed above, so unregister it with the kernel. */ if (self->robust_list.off) - __syscall(SYS_set_robust_list, 0, 3*sizeof(long)); + __syscall(SYS_set_robust_list, 0, 3 * sizeof(long)); /* The following call unmaps the thread's stack mapping * and then exits without touching the stack. */ __unmapself(self->map_base, self->map_size); } #else - if (state==DT_DETACHED && self->map_base) { + if (state == DT_DETACHED && self->map_base) + { /* As we use malloc/free which is considerably more complex * than mmap/munmap to call and can even require a valid * thread context, it's difficult to implement __unmapself. @@ -224,9 +235,18 @@ static void __pthread_exit(void *result) /* Wake any joiner. */ a_store(&self->detach_state, DT_EXITED); __wake(&self->detach_state, 1, 1); - -#ifdef __wasilibc_unmodified_upstream - for (;;) __syscall(SYS_exit, 0); + #ifdef __wasip3__ + // Yield to the joining thread, if any. + // Note that we use yield_to here instead of switch_to, + // so that eventually this thread will get rescheduled + // and can exit properly. + if (self->joining_tid != 0) + wasip3_thread_yield_to(self->joining_tid); + #endif + +#ifdef __wasilibc_unmodified_upstream + for (;;) + __syscall(SYS_exit, 0); #else // Can't use `exit()` here, because it is too high level @@ -235,7 +255,7 @@ static void __pthread_exit(void *result) * this thread terminates. * See also set_tid_address(2) * - * In WebAssembly, we leave it to wasi_thread_start instead. + * In WebAssembly, we leave it to wasi{p3}_thread_start instead. */ #endif } @@ -252,16 +272,17 @@ void __do_cleanup_pop(struct __ptcb *cb) __pthread_self()->cancelbuf = cb->__next; } -struct start_args { +struct start_args +{ #ifdef __wasilibc_unmodified_upstream void *(*start_func)(void *); void *start_arg; volatile int control; - unsigned long sig_mask[_NSIG/8/sizeof(long)]; + unsigned long sig_mask[_NSIG / 8 / sizeof(long)]; #else /* * Note: the offset of the "stack" and "tls_base" members - * in this structure is hardcoded in wasi_thread_start. + * in this structure is hardcoded in wasi{p3}_thread_start. */ void *stack; void *tls_base; @@ -275,18 +296,21 @@ static int start(void *p) { struct start_args *args = p; int state = args->control; - if (state) { - if (a_cas(&args->control, 1, 2)==1) + if (state) + { + if (a_cas(&args->control, 1, 2) == 1) __wait(&args->control, 0, 2, 1); - if (args->control) { + if (args->control) + { #ifdef __wasilibc_unmodified_upstream __syscall(SYS_set_tid_address, &args->control); - for (;;) __syscall(SYS_exit, 0); + for (;;) + __syscall(SYS_exit, 0); #endif } } #ifdef __wasilibc_unmodified_upstream - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->sig_mask, 0, _NSIG/8); + __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->sig_mask, 0, _NSIG / 8); #endif __pthread_exit(args->start_func(args->start_arg)); return 0; @@ -295,12 +319,37 @@ static int start(void *p) static int start_c11(void *p) { struct start_args *args = p; - int (*start)(void*) = (int(*)(void*)) args->start_func; + int (*start)(void *) = (int (*)(void *))args->start_func; __pthread_exit((void *)(uintptr_t)start(args->start_arg)); return 0; } #else +#ifdef __wasip3__ +/* + * We want to ensure wasip3_thread_start is linked whenever + * pthread_create is used. The following reference is to ensure that. + * Otherwise, the linker doesn't notice the dependency because + * wasip3_thread_start is used indirectly via a wasm export. + */ +void wasip3_thread_start(void *context); +hidden void *__dummy_reference = wasip3_thread_start; +void __wasilibc_init_task(void); +hidden void * __dummy_reference_init_task = __wasilibc_init_task; + +hidden void __wasip3_thread_start_C(int tid, void *context) +{ + struct start_args *args = context; + pthread_t self = __pthread_self(); + // Set the thread ID (TID) on the pthread structure. The TID is stored + // atomically since it is also stored by the parent thread; this way, + // whichever thread (parent or child) reaches this point first can proceed + // without waiting. + atomic_store((atomic_int *)&(self->tid), tid); + // Execute the user's start function. + __pthread_exit(args->start_func(args->start_arg)); +} +#else /* * We want to ensure wasi_thread_start is linked whenever * pthread_create is used. The following reference is to ensure that. @@ -318,14 +367,15 @@ hidden void __wasi_thread_start_C(int tid, void *p) // atomically since it is also stored by the parent thread; this way, // whichever thread (parent or child) reaches this point first can proceed // without waiting. - atomic_store((atomic_int *) &(self->tid), tid); + atomic_store((atomic_int *)&(self->tid), tid); // Execute the user's start function. __pthread_exit(args->start_func(args->start_arg)); } #endif +#endif #ifdef __wasilibc_unmodified_upstream -#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE) +#define ROUND(x) (((x) + PAGE_SIZE - 1) & -PAGE_SIZE) #else /* * As we allocate stack with malloc() instead of mmap/mprotect, @@ -333,13 +383,13 @@ hidden void __wasi_thread_start_C(int tid, void *p) * Instead, round up to a sane alignment. * Note: PAGE_SIZE is rather big on WASM. (65536) */ -#define ROUND(x) (((x)+16-1)&-16) +#define ROUND(x) (((x) + 16 - 1) & -16) #endif /* pthread_key_create.c overrides this */ static volatile size_t dummy = 0; weak_alias(dummy, __pthread_tsd_size); -static void *dummy_tsd[1] = { 0 }; +static void *dummy_tsd[1] = {0}; weak_alias(dummy_tsd, __pthread_tsd_main); static FILE *volatile dummy_file = 0; @@ -349,7 +399,8 @@ weak_alias(dummy_file, __stderr_used); static void init_file_lock(FILE *f) { - if (f && f->lock<0) f->lock = 0; + if (f && f->lock < 0) + f->lock = 0; } int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg) @@ -359,34 +410,36 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att struct pthread *self, *new; unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit; #ifdef __wasilibc_unmodified_upstream - unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND - | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS - | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED; + unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED; #endif - pthread_attr_t attr = { 0 }; + pthread_attr_t attr = {0}; sigset_t set; #ifndef __wasilibc_unmodified_upstream size_t tls_size = __builtin_wasm_tls_size(); size_t tls_align = __builtin_wasm_tls_align(); - void* tls_base = __builtin_wasm_tls_base(); - void* new_tls_base; + void *tls_base = __builtin_wasm_tls_base(); + void *new_tls_base; size_t tls_offset; + /* We'll need to allocate space for a correctly-aligned TLS block, + so adjust the size accordingly. */ tls_size += tls_align; #endif #ifdef __wasilibc_unmodified_upstream - if (!libc.can_do_threads) return ENOSYS; + if (!libc.can_do_threads) + return ENOSYS; #endif self = __pthread_self(); - if (!libc.threaded) { - for (FILE *f=*__ofl_lock(); f; f=f->next) + if (!libc.threaded) + { + for (FILE *f = *__ofl_lock(); f; f = f->next) init_file_lock(f); __ofl_unlock(); init_file_lock(__stdin_used); init_file_lock(__stdout_used); init_file_lock(__stderr_used); #ifdef __wasilibc_unmodified_upstream - __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8); + __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG / 8); #endif self->tsd = (void **)__pthread_tsd_main; #ifdef __wasilibc_unmodified_upstream @@ -394,15 +447,18 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att #endif libc.threaded = 1; } - if (attrp && !c11) attr = *attrp; + if (attrp && !c11) + attr = *attrp; __acquire_ptc(); - if (!attrp || c11) { + if (!attrp || c11) + { attr._a_stacksize = __default_stacksize; attr._a_guardsize = __default_guardsize; } - if (attr._a_stackaddr) { + if (attr._a_stackaddr) + { #ifdef __wasilibc_unmodified_upstream size_t need = libc.tls_size + __pthread_tsd_size; #else @@ -414,7 +470,8 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att /* Use application-provided stack for TLS only when * it does not take more than ~12% or 2k of the * application's stack space. */ - if (need < size/8 && need < 2048) { + if (need < size / 8 && need < 2048) + { tsd = stack - __pthread_tsd_size; #ifdef __wasilibc_unmodified_upstream stack = tsd - libc.tls_size; @@ -422,33 +479,43 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att stack = tsd - tls_size; #endif memset(stack, 0, need); - } else { + } + else + { size = ROUND(need); } guard = 0; - } else { + } + else + { guard = ROUND(attr._a_guardsize); size = guard + ROUND(attr._a_stacksize #ifdef __wasilibc_unmodified_upstream - + libc.tls_size + __pthread_tsd_size); + + libc.tls_size + __pthread_tsd_size); #else - + tls_size + __pthread_tsd_size); + + tls_size + __pthread_tsd_size); #endif } - if (!tsd) { + if (!tsd) + { #ifdef __wasilibc_unmodified_upstream - if (guard) { - map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0); - if (map == MAP_FAILED) goto fail; - if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE) - && errno != ENOSYS) { + if (guard) + { + map = __mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (map == MAP_FAILED) + goto fail; + if (__mprotect(map + guard, size - guard, PROT_READ | PROT_WRITE) && errno != ENOSYS) + { __munmap(map, size); goto fail; } - } else { - map = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); - if (map == MAP_FAILED) goto fail; + } + else + { + map = __mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (map == MAP_FAILED) + goto fail; } #else /* Process the deferred free request if any before @@ -460,13 +527,15 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att process_map_base_deferred_free(); __tl_unlock(); map = malloc(size); - if (!map) goto fail; + if (!map) + goto fail; #endif tsd = map + size - __pthread_tsd_size; #ifndef __wasilibc_unmodified_upstream - memset(tsd, 0, __pthread_tsd_size); + memset(tsd, 0, __pthread_tsd_size); #endif - if (!stack) { + if (!stack) + { #ifdef __wasilibc_unmodified_upstream stack = tsd - libc.tls_size; #else @@ -481,7 +550,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att #else new_tls_base = __copy_tls(tsd - tls_size); tls_offset = new_tls_base - tls_base; - new = (void*)((uintptr_t)self + tls_offset); + new = (void *)((uintptr_t)self + tls_offset); #endif new->map_base = map; new->map_size = size; @@ -491,9 +560,12 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att new->self = new; new->tsd = (void *)tsd; new->locale = &libc.global_locale; - if (attr._a_detach) { + if (attr._a_detach) + { new->detach_state = DT_DETACHED; - } else { + } + else + { new->detach_state = DT_JOINABLE; } new->robust_list.head = &new->robust_list.head; @@ -520,8 +592,8 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att * working with a copy of the set so we can restore the * original mask in the calling thread. */ memcpy(&args->sig_mask, &set, sizeof args->sig_mask); - args->sig_mask[(SIGCANCEL-1)/8/sizeof(long)] &= - ~(1UL<<((SIGCANCEL-1)%(8*sizeof(long)))); + args->sig_mask[(SIGCANCEL - 1) / 8 / sizeof(long)] &= + ~(1UL << ((SIGCANCEL - 1) % (8 * sizeof(long)))); #else /* Align the stack to struct start_args */ stack -= sizeof(struct start_args); @@ -529,26 +601,31 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att struct start_args *args = (void *)stack; /* Align the stack to 16 and store it */ - new->stack = (void *)((uintptr_t) stack & -16); + new->stack = (void *)((uintptr_t)stack & -16); /* Correct the stack size */ new->stack_size = stack - stack_limit; args->stack = new->stack; /* just for convenience of asm trampoline */ args->start_func = entry; args->start_arg = arg; - args->tls_base = (void*)new_tls_base; + args->tls_base = (void *)new_tls_base; #endif __tl_lock(); - if (!libc.threads_minus_1++) libc.need_locks = 1; + if (!libc.threads_minus_1++) + libc.need_locks = 1; #ifdef __wasilibc_unmodified_upstream ret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock); +#else +#ifdef __wasip3__ + ret = wasip3_thread_new_indirect(wasip3_thread_start, (void *)args); #else /* Instead of `__clone`, WASI uses a host API to instantiate a new version * of the current module and start executing the entry function. The * wasi-threads specification requires the module to export a * `wasi_thread_start` function, which is invoked with `args`. */ - ret = __wasi_thread_spawn((void *) args); + ret = __wasi_thread_spawn((void *)args); +#endif #endif #ifdef __wasilibc_unmodified_upstream @@ -556,12 +633,15 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att * was requested, attempt it before unlocking the thread list so * that the failed thread is never exposed and so that we can * clean up all transient resource usage before returning. */ - if (ret < 0) { + if (ret < 0) + { ret = -EAGAIN; - } else if (attr._a_sched) { + } + else if (attr._a_sched) + { ret = __syscall(SYS_sched_setscheduler, - new->tid, attr._a_policy, &attr._a_prio); - if (a_swap(&args->control, ret ? 3 : 0)==2) + new->tid, attr._a_policy, &attr._a_prio); + if (a_swap(&args->control, ret ? 3 : 0) == 2) __wake(&args->control, 1, 1); if (ret) __wait(&args->control, 0, 3, 0); @@ -578,20 +658,27 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att * to set this field; this way, whichever thread reaches this point first * can continue without waiting. */ assert(ret != 0 && ret <= WASI_THREADS_MAX_TID); - if (ret < 0) { + if (ret < 0) + { ret = -EAGAIN; - } else { - atomic_store((atomic_int *) &(new->tid), ret); + } + else + { + atomic_store((atomic_int *)&(new->tid), ret); } #endif - if (ret >= 0) { + if (ret >= 0) + { new->next = self->next; new->prev = self; new->next->prev = new; new->prev->next = new; - } else { - if (!--libc.threads_minus_1) libc.need_locks = 0; + } + else + { + if (!--libc.threads_minus_1) + libc.need_locks = 0; } __tl_unlock(); #ifdef __wasilibc_unmodified_upstream @@ -599,15 +686,21 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att #endif __release_ptc(); - if (ret < 0) { + if (ret < 0) + { #ifdef __wasilibc_unmodified_upstream - if (map) __munmap(map, size); + if (map) + __munmap(map, size); #else free(map); #endif return -ret; } +#ifdef __wasip3__ + wasip3_thread_yield_to(new->tid); +#endif + *res = new; return 0; fail: diff --git a/libc-top-half/musl/src/thread/pthread_join.c b/libc-top-half/musl/src/thread/pthread_join.c index b06e7e75e..65fe3d273 100644 --- a/libc-top-half/musl/src/thread/pthread_join.c +++ b/libc-top-half/musl/src/thread/pthread_join.c @@ -32,8 +32,17 @@ static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec } int __pthread_join(pthread_t t, void **res) -{ +{ + #ifdef __wasip3__ + if (t->detach_state != DT_EXITED) { + t->joining_tid = wasip3_thread_index(); + wasip3_thread_switch_to(t->tid); + } + if (res) *res = t->result; + return 0; + #else return __pthread_timedjoin_np(t, res, 0); + #endif } static int __pthread_tryjoin_np(pthread_t t, void **res) diff --git a/libc-top-half/musl/src/thread/wasm32/wasip3_thread_start.s b/libc-top-half/musl/src/thread/wasm32/wasip3_thread_start.s new file mode 100644 index 000000000..b140f618b --- /dev/null +++ b/libc-top-half/musl/src/thread/wasm32/wasip3_thread_start.s @@ -0,0 +1,54 @@ + .text + + .export_name wasip3_thread_start, wasip3_thread_start + + .globaltype __init_stack_pointer, i32 + .functype __wasip3_thread_start_C (i32, i32) -> () + .functype __wasm_component_model_builtin_context_set_0 (i32) -> () + .import_module __wasm_component_model_builtin_context_set_0, "$root" + .import_name __wasm_component_model_builtin_context_set_0, "[context-set-0]" + .functype __wasm_component_model_builtin_context_set_1 (i32) -> () + .import_module __wasm_component_model_builtin_context_set_1, "$root" + .import_name __wasm_component_model_builtin_context_set_1, "[context-set-1]" + .import_module __wasm_component_model_builtin_thread_index, "$root" + .import_name __wasm_component_model_builtin_thread_index, "[thread-index]" + .functype __wasm_component_model_builtin_thread_index () -> (i32) + + .hidden wasip3_thread_start + .globl wasip3_thread_start + .type wasip3_thread_start,@function + +wasip3_thread_start: + .functype wasip3_thread_start (i32) -> () + + # Set up the minimum C environment. + local.get 0 # start_arg + i32.load 0 # stack + call __wasm_component_model_builtin_context_set_0 + + local.get 0 # start_arg + i32.load 4 # tls_base + call __wasm_component_model_builtin_context_set_1 + # Make the C function do the rest of work. + call __wasm_component_model_builtin_thread_index + local.get 0 # start_arg + call __wasip3_thread_start_C + + # Unlock thread list. (as CLONE_CHILD_CLEARTID would do for Linux) + # + # Note: once we unlock the thread list, our "map_base" can be freed + # by a joining thread. It's safe as we are in ASM and no longer use + # our C stack or pthread_t. It's impossible to do this safely in C + # because there is no way to tell the C compiler not to use C stack. + i32.const __thread_list_lock + i32.const 0 + i32.atomic.store 0 + # As an optimization, we can check tl_lock_waiters here. + # But for now, simply wake up unconditionally as + # CLONE_CHILD_CLEARTID does. + i32.const __thread_list_lock + i32.const 1 + memory.atomic.notify 0 + drop + + end_function \ No newline at end of file diff --git a/test/src/coop_thread.c b/test/src/coop_thread.c new file mode 100644 index 000000000..a50fb088e --- /dev/null +++ b/test/src/coop_thread.c @@ -0,0 +1,44 @@ +#include +#include +#include +void *thread_start(void *arg) +{ + // A thread local, which should have a separate address per-thread, but the same initial value. + static _Thread_local int my_thread_local = 55; + static int my_non_thread_local = 100; + printf("Thread started: arg=%lu, my_thread_local(%p)=%d, my_non_thread_local=%d\n", + (uintptr_t)arg, (void *)&my_thread_local, my_thread_local, my_non_thread_local); + + sched_yield(); + printf("Thread resumed: arg=%lu, my_thread_local(%p)=%d, my_non_thread_local=%d\n", + (uintptr_t)arg, (void *)&my_thread_local, my_thread_local, my_non_thread_local); + + // This should not affect other threads' copies of the thread local. + my_thread_local += (uintptr_t)arg; + my_non_thread_local += (uintptr_t)arg; + + return (void *)((uintptr_t)arg + 100); +} + +int main() +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_t threads[3]; + + printf("Creating threads...\n"); + pthread_create(&threads[0], &attr, &thread_start, (void *)12); + pthread_create(&threads[1], &attr, &thread_start, (void *)13); + pthread_create(&threads[2], &attr, &thread_start, (void *)14); + printf("Threads created!\n"); + + void *ret; + pthread_join(threads[0], &ret); + printf("Thread 1 returned: %lu\n", (uintptr_t)ret); + + pthread_join(threads[1], &ret); + printf("Thread 2 returned: %lu\n", (uintptr_t)ret); + + pthread_join(threads[2], &ret); + printf("Thread 3 returned: %lu\n", (uintptr_t)ret); +} diff --git a/wasi/wasi-libc-wasip2.wit.in b/wasi/wasi-libc-wasip2.wit.in new file mode 100644 index 000000000..a68af3929 --- /dev/null +++ b/wasi/wasi-libc-wasip2.wit.in @@ -0,0 +1,11 @@ +package wasi-libc:wasip2; + +world wasip2 { + include wasi:cli/command@${wasip2-version}; + include wasi:clocks/imports@${wasip2-version}; + include wasi:filesystem/imports@${wasip2-version}; + include wasi:http/proxy@${wasip2-version}; + include wasi:random/imports@${wasip2-version}; + include wasi:io/imports@${wasip2-version}; + include wasi:sockets/imports@${wasip2-version}; +} \ No newline at end of file diff --git a/wasi/wasi-libc-wasip3.wit.in b/wasi/wasi-libc-wasip3.wit.in new file mode 100644 index 000000000..e4f586bd3 --- /dev/null +++ b/wasi/wasi-libc-wasip3.wit.in @@ -0,0 +1,10 @@ +package wasi-libc:wasip3; + +world wasip3 { + include wasi:cli/command@${wasip3-version}; + include wasi:clocks/imports@${wasip3-version}; + include wasi:filesystem/imports@${wasip3-version}; + include wasi:http/middleware@${wasip3-version}; + include wasi:random/imports@${wasip3-version}; + include wasi:sockets/imports@${wasip3-version}; +} \ No newline at end of file