Skip to content

Commit

Permalink
support System.Net.Http.HttpClient on WASIp2
Browse files Browse the repository at this point in the history
This adds `WasiHttpHandler`, a new implementation of `HttpMessageHandler` based
on
[wasi:http/outgoing-handler](https://github.com/WebAssembly/wasi-http/blob/v0.2.0/wit/handler.wit),
plus tweaks to `System.Threading` to allow async `Task`s to work in a
single-threaded context, with `ThreadPool` work items dispatched from an
application-provided event loop.

WASIp2 supports asynchronous I/O and timers via `wasi:io/poll/pollable` resource
handles.  One or more of those handles may be passed to `wasi:io/poll/poll`,
which will block until at least one of them is ready.  In order to make this
model play nice with C#'s `async`/`await` and `Task` features, we need to
reconcile several constraints:

- WASI is currently single-threaded, and will continue to be that way for a while.
- C#'s `async`/`await` and `Task` features require a working `ThreadPool` implementation capable of deferring work.
- A WASI component can export an arbitrary number of functions to the host, and though they will always be called synchronously from the host, they need to be able to perform asynchronous operations before returning.
- WASIp3 (currently in the design and prototype phase) will support asynchronous exports, with the top level event loop running in the host instead of the guest, and `wasi:io/poll/pollable` will no longer exist.  Therefore, we don't want to add any temporary public APIs to the .NET runtime which will become obsolete when WASIp3 arrives.

The solution we arrived at looks something like this:

- Tweak the existing `ThreadPool` implementation for WASI so that methods such as `RequestWorkerThread` don't throw `PlatformNotSupportedException`s (i.e. allow work items to be queued even though the "worker thread" is always the same one that is queuing the work)
- Add two new methods to `Thread`:
    - `internal static void Dispatch`: Runs an iteration of event loop, draining the `ThreadPool` queue of ready work items and calling `wasi:io/poll/poll` with any accumulated `pollable` handles
    - `internal static Task Register(int pollableHandle)`: Registers the specified `pollable` handle to be `poll`ed during the next call to `Dispatch`
    - Note that these methods are `internal` because they're temporary and should not be part of the public API, but they are intended to be called via `UnsafeAccessor` by application code (or more precisely, code generated by `wit-bindgen` for the application)

The upshot is that application code can use `wit-bindgen` (either directly or
via the new `componentize-dotnet` package) to generate async export bindings
which will provide an event loop backed by `Thread.Dispatch`.  Additionally,
`wit-bindgen` can transparently convert any `pollable` handles returned by WASI
imports into `Task`s via `Thread.Register`, allowing the component to `await`
them, pass them to a combinator such as `Task.WhenEach`, etc.

Later, when WASIp3 arrives and we update the .NET runtime to target it, we'll be
able to remove some of this code (and the corresponding code in `wit-bindgen`)
without requiring significant changes to the application developer's experience.

This PR contains a few C# source files that were generated by `wit-bindgen` from
the official WASI WIT files, plus scripts to regenerate them if desired.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

switch to `wasm32-wasip2` and update WASI test infra

Now that we're using WASI-SDK 22, we can target `wasm32-wasip2`, which produces
components by default and includes full `wasi:sockets` support.  In order to run
those components, I've updated the test infrastructure to use Wasmtime 21 (the
latest release as of this writing).

Other changes of note:

- Tweaked src/coreclr/jit/compiler.cpp to make `Debug` builds work on Linux

- Added libWasiHttp.a, which includes the encoded component type (in the form of a pre-generated Wasm object file) and a `cabi_realloc` definition.  Both of these are generated by `wit-bindgen` and required by `wasm-component-ld` to generate a valid component.

- Added a `FindWasmHostExecutableAndRun.sh` script for running the WASI tests on UNIX-style platforms.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

various WASI build tweaks

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

quote libWasiHttp.a path in custom linker arg

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

fix wasm-component-ld download command

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

tweak EmccExtraArgs in CustomMain.csproj so wasm-component-ld understands it

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

update CMake minimum version in wasi-sdk-p2.cmake

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

use `HeaderDescriptor` to sort content and response headers

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

allow building native WASI test code in src/tests/build.sh

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

allow WASI runtime tests to be built and run on non-Windows systems

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

update runtime tests to work with WASIp2

As of this writing, WASIp2 [does not support process exit
statuses](WebAssembly/wasi-cli#11) beyond 0 (success)
and 1 (failure).  To work around this, I've modified the relevant tests to
return 0 on success instead of 100.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

fix CI for Windows builds; remove unused file

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

disable sprintf warning in llvmlssa.cpp on macOS

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

remove LibraryWorld_cabi_realloc.o

I didn't mean to add this to Git.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

rename `generate-bindings.sh` files for clarity

This makes it more obvious that, though they are similar, they each have a
different job.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

update to `wit-bindgen` 0.27.0 and regenerate bindings

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

reorganize code; add HttpClient smoke test

- move System/WASIp2 to System/Threading/WASIp2
- remove generated `cabi_realloc` functions since `wasi-libc` will provide one
- add HttpClient test to SmokeTests/SharedLibrary

Note that I put the HttpClient test in SmokeTests/SharedLibrary since we were
already using NodeJS for that test, and adding a simple loopback webserver to
SharedLibraryDriver.mjs was easiest option available to keep the whole test
self-contained.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

implement SystemNative_SysLog for WASI

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

increase NodeJS stack trace limit to 200

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

give guest no filesystem access in SharedLibraryDriver.mjs

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

switch to Trace.Assert into HttpClient smoke test

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

rename WASIp2 directory to Wasi

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

fix non-GET methods and add HttpClient echo test

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

use azure NPM

rename

- WasiEventLoop.RegisterWasiPollable
- WasiEventLoop.DispatchWasiEventLoop

to make it less confusing on the Thread class

- unification of gen-buildsys

- cleanup pal_process_wasi.c

fix build?

more

buffer /echo request body in SharedLibraryDriver.mjs

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

fix gen-buildsys.sh regression

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

allow only infinite `HttpClient.Timeout`s on WASI

This temporary code will be reverted once we support `System.Threading.Timer` on
WASI in a forthcoming PR.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

use `&` operator to simplify install-jco.ps1

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

remove redundant `CheckWasmSdks` target from SharedLibrary.csproj

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

split `FindWasmHostExecutable.sh` out of `FindWasmHostExecutableAndRun.sh`

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

replace component type object files with WIT files

This updates `wit-bindgen` and `wasm-component-ld`, which now support producing
and consuming component type WIT files as an alternative to binary object files.
These files are easier to audit from a security perspective.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

preserve slashes in path in SharedLibrary.csproj

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
  • Loading branch information
dicej committed Jul 17, 2024
1 parent 0addb56 commit 8dcb2ae
Show file tree
Hide file tree
Showing 87 changed files with 11,493 additions and 112 deletions.
4 changes: 3 additions & 1 deletion docs/workflow/building/coreclr/nativeaot.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ For the runtime libraries:
./emsdk install 3.1.47
./emsdk activate 3.1.47
```
- To build for WASI, download and install WASI-SDK 22 from https://github.com/WebAssembly/wasi-sdk/releases (only Windows and Linux are supported currently) and set the `WASI_SDK_PATH` environment variable to the location where it is installed, e.g. `set WASI_SDK_PATH=c:\github\wasi-sdk`. Note that WASI-SDK 22 only includes a copy of `pthread.h` for the `wasm32-wasi-threads` target, which we must copy to the include directory for the `wasm32-wasi` target, e.g. `cp $WASI_SDK\share\wasi-sysroot\include\wasm32-wasi-threads\pthread.h $WASI_SDK\share\wasi-sysroot\include\wasm32-wasi\`. This is a temporary workaround until https://github.com/WebAssembly/wasi-libc/issues/501 has been addressed and released.
- To build for WASI, download and install WASI-SDK 22 from https://github.com/WebAssembly/wasi-sdk/releases (only Windows and Linux are supported currently) and set the `WASI_SDK_PATH` environment variable to the location where it is installed, e.g. `set WASI_SDK_PATH=c:\github\wasi-sdk`.
- Note that WASI-SDK 22 only includes a copy of `pthread.h` for the `wasm32-wasi-threads` target, which we must copy to the include directory for the `wasm32-wasip2` target, e.g. `cp %WASI_SDK_PATH%\share\wasi-sysroot\include\wasm32-wasi-threads\pthread.h %WASI_SDK_PATH%\share\wasi-sysroot\include\wasm32-wasip2\`. This is a temporary workaround until https://github.com/WebAssembly/wasi-libc/issues/501 has been addressed and released.
- Also, due to [this bug](https://github.com/bytecodealliance/wasm-component-ld/issues/22), we need to replace the `wasm-component-ld` that ships with WASI-SDK 22 with an updated version. If you have [cargo](https://rustup.rs/), you can run e.g. `cargo install wasm-component-ld@0.5.5 --root %WASI_SDK_PATH%`; otherwise, you can download it from [here](https://github.com/bytecodealliance/wasm-component-ld/releases/tag/v0.5.5), extract the binary, and copy it into `%WASI_SDK_PATH%\bin`.
- Run `build clr.aot+libs -c [Debug|Release] -a wasm -os [browser|wasi]`. This will create the architecture-dependent libraries needed for linking and runtime execution, as well as the managed binaries to be used as input to ILC.

For the compilers:
Expand Down
4 changes: 3 additions & 1 deletion eng/native/gen-buildsys.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ if /i "%__Arch%" == "wasm" (
set __UseEmcmake=1
)
if /i "%__Os%" == "wasi" (
set "__repoRoot=!__repoRoot:\=/!"
if not "!__repoRoot:~-1!" == "/" set "__repoRoot=!__repoRoot!/"
if "%WASI_SDK_PATH%" == "" (
if not exist "%__repoRoot%\src\mono\wasi\wasi-sdk" (
echo Error: Should set WASI_SDK_PATH environment variable pointing to WASI SDK root.
Expand All @@ -63,7 +65,7 @@ if /i "%__Arch%" == "wasm" (
set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!"
if not "!WASI_SDK_PATH:~-1!" == "/" set "WASI_SDK_PATH=!WASI_SDK_PATH!/"
set __CmakeGenerator=Ninja
set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk.cmake" -DCMAKE_CROSSCOMPILING_EMULATOR="%EMSDK_NODE% --experimental-wasm-bigint --experimental-wasi-unstable-preview1"
set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!__repoRoot!/src/native/external/wasi-sdk-p2.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!share/wasi-sysroot" "-DCMAKE_CROSSCOMPILING_EMULATOR=!EMSDK_NODE! --experimental-wasm-bigint --experimental-wasi-unstable-preview1"
)
) else (
set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_SYSTEM_VERSION=10.0"
Expand Down
3 changes: 2 additions & 1 deletion eng/native/gen-buildsys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#

scriptroot="$( cd -P "$( dirname "$0" )" && pwd )"
reporoot="$(cd "$scriptroot"/../..; pwd -P)"

if [[ "$#" -lt 4 ]]; then
echo "Usage..."
Expand Down Expand Up @@ -103,7 +104,7 @@ if [[ "$host_arch" == "wasm" ]]; then
exit 1
fi

cmake_extra_defines_wasm=("-DCLR_CMAKE_TARGET_OS=wasi" "-DCLR_CMAKE_TARGET_ARCH=wasm" "-DWASI_SDK_PREFIX=$WASI_SDK_PATH" "-DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk.cmake" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1")
cmake_extra_defines_wasm=("-DCLR_CMAKE_TARGET_OS=wasi" "-DCLR_CMAKE_TARGET_ARCH=wasm" "-DWASI_SDK_PREFIX=$WASI_SDK_PATH" "-DCMAKE_TOOLCHAIN_FILE=$reporoot/src/native/external/wasi-sdk-p2.cmake" "-DCMAKE_SYSROOT=${WASI_SDK_PATH}/share/wasi-sysroot" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1")
else
echo "target_os was not specified"
exit 1
Expand Down
8 changes: 5 additions & 3 deletions eng/pipelines/common/global-build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,13 @@ jobs:
displayName: Install NodeJS

- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.platform, 'wasi_wasm_win')) }}:
# Install Wasi Wasm dependencies: wasi-sdk, wasmer
# Install Wasi Wasm dependencies: wasi-sdk, wasmtime
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasi-sdk.cmd $(Build.SourcesDirectory)\wasm-tools
displayName: Install wasi-sdk
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasmer.cmd $(Build.SourcesDirectory)\wasm-tools
displayName: Install wasmer
- script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasmtime.cmd $(Build.SourcesDirectory)\wasm-tools
displayName: Install wasmtime
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-jco.ps1 $(Build.SourcesDirectory)
displayName: Install Jco

- ${{ if or(eq(parameters.platform, 'browser_wasm_win'), and(eq(parameters.platform, 'wasi_wasm_win'), not(eq(parameters.runtimeFlavor, 'coreclr')))) }}:
# Update machine certs
Expand Down
9 changes: 9 additions & 0 deletions eng/pipelines/runtimelab/install-jco.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$RootPath = $Args[0]

$NpmExePath = $Env:NPM_EXECUTABLE

Set-Location -Path $RootPath

& $NpmExePath install @bytecodealliance/jco
& $NpmExePath install @bytecodealliance/preview2-shim

11 changes: 11 additions & 0 deletions eng/pipelines/runtimelab/install-nodejs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ if ($IsWindows)
{
Expand-Archive -LiteralPath "$InstallPath\$NodeJSZipName" -DestinationPath $InstallPath -Force
$NodeJSExePath = "$InstallPath\$NodeJSInstallName\node.exe"
$NpmExePath = "$InstallPath\$NodeJSInstallName\npm.cmd"
}
else
{
tar xJf $InstallPath/$NodeJSZipName -C $InstallPath
$NodeJSExePath = "$InstallPath/$NodeJSInstallName/bin/node"
$NpmExePath = "$InstallPath/$NodeJSInstallName/bin/npm"
}

if (!(Test-Path $NodeJSExePath))
Expand All @@ -64,5 +66,14 @@ if (!(Test-Path $NodeJSExePath))
exit 1
}

if (!(Test-Path $NpmExePath))
{
Write-Error "Did not find NPM at: '$NpmExePath'"
exit 1
}

Write-Host Setting NODEJS_EXECUTABLE to $NodeJSExePath
Write-Host "##vso[task.setvariable variable=NODEJS_EXECUTABLE]$NodeJSExePath"

Write-Host Setting NPM_EXECUTABLE to $NpmExePath
Write-Host "##vso[task.setvariable variable=NPM_EXECUTABLE]$NpmExePath"
16 changes: 14 additions & 2 deletions eng/pipelines/runtimelab/install-wasi-sdk.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@ mv wasi-sdk-22.0+m wasi-sdk

# Temporary WASI-SDK 22 workaround: Until
# https://github.com/WebAssembly/wasi-libc/issues/501 is addressed, we copy
# pthread.h from the wasm32-wasi-threads include directory to the wasm32-wasi
# pthread.h from the wasm32-wasi-threads include directory to the wasm32-wasip2
# include directory. See https://github.com/dotnet/runtimelab/issues/2598 for
# the issue to remove this workaround once WASI-SDK 23 is released.

cp wasi-sdk/share/wasi-sysroot/include/wasm32-wasi-threads/pthread.h wasi-sdk/share/wasi-sysroot/include/wasm32-wasi/
cp wasi-sdk/share/wasi-sysroot/include/wasm32-wasi-threads/pthread.h wasi-sdk/share/wasi-sysroot/include/wasm32-wasip2/

# Temporary WASI-SDK 22 workaround #2: The version of `wasm-component-ld` that
# ships with WASI-SDK 22 contains a
# [bug](https://github.com/bytecodealliance/wasm-component-ld/issues/22) which
# has been fixed in a v0.5.3 of that utility, so we upgrade it here. Also,
# v0.5.5 adds support for a `--component-type` option, helping us avoid adding
# .o files to source control.

Invoke-WebRequest -Uri https://github.com/bytecodealliance/wasm-component-ld/releases/download/v0.5.5/wasm-component-ld-v0.5.5-x86_64-windows.zip -OutFile wasm-component-ld-v0.5.5-x86_64-windows.zip

Expand-Archive -LiteralPath wasm-component-ld-v0.5.5-x86_64-windows.zip -DestinationPath .
cp wasm-component-ld-v0.5.5-x86_64-windows/wasm-component-ld.exe wasi-sdk/bin
16 changes: 0 additions & 16 deletions eng/pipelines/runtimelab/install-wasmer.cmd

This file was deleted.

5 changes: 0 additions & 5 deletions eng/pipelines/runtimelab/install-wasmer.ps1

This file was deleted.

16 changes: 16 additions & 0 deletions eng/pipelines/runtimelab/install-wasmtime.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
mkdir "%1" 2>nul
cd /D "%1"

echo Installing Wasmtime

powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -File "%~dp0install-wasmtime.ps1"
if %errorlevel% NEQ 0 goto fail

echo Setting WASMTIME_EXECUTABLE to %1\wasmtime\bin\wasmtime.exe
echo ##vso[task.setvariable variable=WASMTIME_EXECUTABLE]%1\wasmtime\bin\wasmtime.exe

exit /b 0

fail:
echo "Failed to install wasmtime"
exit /b 1
8 changes: 8 additions & 0 deletions eng/pipelines/runtimelab/install-wasmtime.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Invoke-WebRequest -Uri https://github.com/bytecodealliance/wasmtime/releases/download/v21.0.1/wasmtime-v21.0.1-x86_64-windows.zip -OutFile wasmtime-v21.0.1-x86_64-windows.zip

mkdir wasmtime\bin

Expand-Archive -LiteralPath wasmtime-v21.0.1-x86_64-windows.zip -DestinationPath .
del wasmtime-v21.0.1-x86_64-windows.zip
move wasmtime-v21.0.1-x86_64-windows\wasmtime.exe wasmtime\bin\
Remove-Item -Recurse wasmtime-v21.0.1-x86_64-windows
8 changes: 4 additions & 4 deletions eng/testing/FindWasmHostExecutable.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ if exist "%__WasmBinaryPathWithoutExtension%.js" (
)

if "%__WasmBinaryExtension%" == ".wasm" (
if "%WASMER_EXECUTABLE%" == "" (
:: When running tests locally, assume wasmer is in PATH.
set WASMER_EXECUTABLE=wasmer
if "%WASMTIME_EXECUTABLE%" == "" (
:: When running tests locally, assume wasmtime is in PATH.
set WASMTIME_EXECUTABLE=wasmtime
)

set WASM_HOST_EXECUTABLE="!WASMER_EXECUTABLE!" --
set WASM_HOST_EXECUTABLE="!WASMTIME_EXECUTABLE!" run -S http
) else (
if "%NODEJS_EXECUTABLE%" == "" (
:: When running tests locally, assume NodeJS is in PATH.
Expand Down
24 changes: 24 additions & 0 deletions eng/testing/FindWasmHostExecutable.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

exename=$(basename "$1" .dll)
dirname=$(dirname "$1")

node="node --stack_trace_limit=100"
wasmtime="wasmtime run -S http"

if [ -e "${dirname}/${exename}.js" ]; then
WASM_HOST_EXECUTABLE=$node
WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.js"
elif [ -e "${dirname}/main.js" ]; then
WASM_HOST_EXECUTABLE=$node
WASM_BINARY_TO_EXECUTE="${dirname}/main.js"
elif [ -e "${dirname}/${exename}.mjs" ]; then
WASM_HOST_EXECUTABLE=$node
WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.mjs"
elif [ -e "${dirname}/main.mjs" ]; then
WASM_HOST_EXECUTABLE=$node
WASM_BINARY_TO_EXECUTE="${dirname}/main.mjs"
elif [ -e "${dirname}/${exename}.wasm" ]; then
WASM_HOST_EXECUTABLE=$wasmtime
WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.wasm"
fi
12 changes: 12 additions & 0 deletions eng/testing/FindWasmHostExecutableAndRun.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)

source $SCRIPT_DIR/FindWasmHostExecutable.sh "$1"

if [ -n "${WASM_HOST_EXECUTABLE}" ]; then
echo $WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:2}"
$WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:2}"
else
exit 1
fi
8 changes: 5 additions & 3 deletions src/coreclr/build-runtime.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,11 @@ for /f "delims=" %%a in ("-%__RequestedBuildComponents%-") do (
set __CMakeTarget=!__CMakeTarget! nativeaot

if "%__TargetArch%"=="wasm" (
if not defined EMSDK (
echo %__ErrMsgPrefix%%__MsgPrefix%Error: The EMSDK environment variable pointing to emsdk root must be set.
goto ExitWithError
if "%__TargetOS%"=="browser" (
if not defined EMSDK (
echo %__ErrMsgPrefix%%__MsgPrefix%Error: The EMSDK environment variable pointing to emsdk root must be set.
goto ExitWithError
)
)
)
)
Expand Down
10 changes: 7 additions & 3 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,8 +1275,12 @@ void DisplayNowayAssertMap()
fout = _wfopen(strJitMeasureNowayAssertFile, W("a"));
if (fout == nullptr)
{
#if !defined(TARGET_WINDOWS)
// TODO: how do we print a `const char16_t*` portably?
#else
fprintf(jitstdout(), "Failed to open JitMeasureNowayAssertFile \"%ws\"\n",
strJitMeasureNowayAssertFile);
#endif
return;
}
}
Expand Down Expand Up @@ -1308,7 +1312,7 @@ void DisplayNowayAssertMap()

for (i = 0; i < count; i++)
{
fprintf(fout, "%u, %s, %u, \"%s\"\n", nacp[i].count, nacp[i].fl.m_file, nacp[i].fl.m_line,
fprintf(fout, "%u, %s, %u, \"%s\"\n", (unsigned int) nacp[i].count, nacp[i].fl.m_file, nacp[i].fl.m_line,
nacp[i].fl.m_condStr);
}

Expand Down Expand Up @@ -3426,7 +3430,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
if (verbose)
{
printf("STRESS_NULL_OBJECT_CHECK: compMaxUncheckedOffsetForNullObject=0x%X\n",
compMaxUncheckedOffsetForNullObject);
(unsigned int) compMaxUncheckedOffsetForNullObject);
}
}

Expand Down Expand Up @@ -9645,7 +9649,7 @@ void dumpConvertedVarSet(Compiler* comp, VARSET_VALARG_TP vars)
{
printf(" ");
}
printf("V%02u", varNum);
printf("V%02u", (unsigned int) varNum);
first = false;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/llvmlssa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,7 @@ class ShadowStackAllocator
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif // __clang__
if (pBuffer == nullptr)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ The .NET Foundation licenses this file to you under the MIT license.
<WasmOptimizationSetting Condition="$(Optimize) == 'true' and $(OptimizationPreference) == 'Size'">-Oz</WasmOptimizationSetting>

<IlcLlvmTarget Condition="'$(_targetOS)' == 'browser'">wasm32-unknown-emscripten</IlcLlvmTarget>
<IlcLlvmTarget Condition="'$(_targetOS)' == 'wasi'">wasm32-unknown-wasi</IlcLlvmTarget>
<IlcLlvmTarget Condition="'$(_targetOS)' == 'wasi'">wasm32-unknown-wasip2</IlcLlvmTarget>
<IlcWasmStackSize>1048576</IlcWasmStackSize> <!-- 1MB -->
<IlcWasmStackSize Condition="'$(EmccStackSize)' != ''">$(EmccStackSize)</IlcWasmStackSize>
<IlcWasmGlobalBase>1024</IlcWasmGlobalBase> <!-- This value is also hardcoded in the compiler -->
Expand Down Expand Up @@ -586,6 +586,7 @@ The .NET Foundation licenses this file to you under the MIT license.
<CustomLinkerArg Include="-Wl,--global-base=$(IlcWasmGlobalBase)" />
<CustomLinkerArg Include="-Wl,-z,stack-size=$(IlcWasmStackSize)" />
<CustomLinkerArg Include="-mexec-model=reactor" Condition="'$(NativeLib)' == 'Shared'" />
<CustomLinkerArg Include="-Wl,--component-type,&quot;$(IlcSdkPath.Replace(&quot;\&quot;, &quot;/&quot;))WasiHttpWorld_component_type.wit&quot;" />
</ItemGroup>

<ItemGroup>
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ if (NOT CLR_CMAKE_TARGET_ARCH_WASM)
install_static_library(standalonegc-enabled aotsdk nativeaot)
endif()

if (CLR_CMAKE_TARGET_WASI)
install(
FILES ../../../../libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpWorld_component_type.wit
DESTINATION aotsdk
COMPONENT nativeaot
)
endif()
17 changes: 16 additions & 1 deletion src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,22 @@
Link="Common\System\Net\Http\HttpHandlerDefaults.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'wasi'">
<Reference Include="System.Threading.Thread" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpHandler.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttp.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.clocks.v0_2_0.MonotonicClockInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.ITypes.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.OutgoingHandlerInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.TypesInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.ErrorInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IError.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IPoll.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IStreams.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.PollInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.StreamsInterop.cs" />
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.Win32.Primitives" />
<Reference Include="System.Collections.NonGeneric" />
Expand Down Expand Up @@ -508,5 +524,4 @@
<ItemGroup>
<None Include="Resources\SR.resx" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ public partial class HttpClient : HttpMessageInvoker
#region Fields

private static IWebProxy? s_defaultProxy;
#if TARGET_WASI
// TODO: remove this WASI-specific code once `System.Threading.Timer` is supported
private static readonly TimeSpan s_defaultTimeout = Threading.Timeout.InfiniteTimeSpan;
#else
private static readonly TimeSpan s_defaultTimeout = TimeSpan.FromSeconds(100);
#endif
private static readonly TimeSpan s_maxTimeout = TimeSpan.FromMilliseconds(int.MaxValue);
private static readonly TimeSpan s_infiniteTimeout = Threading.Timeout.InfiniteTimeSpan;
private const HttpCompletionOption DefaultCompletionOption = HttpCompletionOption.ResponseContentRead;
Expand Down Expand Up @@ -106,6 +111,10 @@ public TimeSpan Timeout
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(value, TimeSpan.Zero);
ArgumentOutOfRangeException.ThrowIfGreaterThan(value, s_maxTimeout);
#if TARGET_WASI
// TODO: remove this WASI-specific code once `System.Threading.Timer` is supported
throw new PlatformNotSupportedException("finite timeouts not yet supported on WASI");
#endif
}
CheckDisposedOrStarted();
_timeout = value;
Expand Down
Loading

0 comments on commit 8dcb2ae

Please sign in to comment.