diff --git a/Directory.Build.props b/Directory.Build.props
index 76b4d1aa9dd77..e0a179b742317 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -28,6 +28,8 @@
<_hostArch>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant)
$(_hostArch)
+ wasm
+ wasm
arm
armv6
armel
@@ -35,8 +37,6 @@
loongarch64
s390x
ppc64le
- wasm
- wasm
x64
x64
$(TargetArchitecture)
diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets
index 9f29ab2f4849d..5df409f12a259 100644
--- a/eng/liveBuilds.targets
+++ b/eng/liveBuilds.targets
@@ -221,6 +221,18 @@
IsNative="true" />
+
+
+
+
+
+
diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd
index 8e635f3537ac9..78bf2b4e9a027 100644
--- a/eng/native/gen-buildsys.cmd
+++ b/eng/native/gen-buildsys.cmd
@@ -66,7 +66,7 @@ if /i "%__Arch%" == "wasm" (
exit /B 1
)
- set "WASI_SDK_PATH=%__repoRoot%src\mono\wasi\wasi-sdk"
+ set "WASI_SDK_PATH=%__repoRoot%\src\mono\wasi\wasi-sdk"
)
:: replace backslash with forward slash and append last slash
set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!"
diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml
index c41d31f65aa30..49a64403a2f38 100644
--- a/eng/pipelines/common/global-build-job.yml
+++ b/eng/pipelines/common/global-build-job.yml
@@ -171,14 +171,13 @@ jobs:
df -h
displayName: Disk Usage before Build
- - ${{ if eq(parameters.platform, 'browser_wasm_win') }}:
+ - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}:
# Update machine certs
- task: PowerShell@2
displayName: Update machine certs
inputs:
filePath: $(Build.SourcesDirectory)/eng/pipelines/mono/update-machine-certs.ps1
-
# Build
- ${{ if eq(parameters.isSourceBuild, false) }}:
- ${{ if eq(parameters.isManualCodeQLBuild, true) }}:
diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml
index d240154ed814a..ff5333e089cbf 100644
--- a/eng/pipelines/common/platform-matrix.yml
+++ b/eng/pipelines/common/platform-matrix.yml
@@ -379,6 +379,26 @@ jobs:
buildConfig: ${{ parameters.buildConfig }}
${{ insert }}: ${{ parameters.jobParameters }}
+# WASI WebAssembly windows
+
+- ${{ if containsValue(parameters.platforms, 'wasi_wasm_win') }}:
+ - template: xplat-setup.yml
+ parameters:
+ jobTemplate: ${{ parameters.jobTemplate }}
+ helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }}
+ variables: ${{ parameters.variables }}
+ osGroup: wasi
+ archType: wasm
+ targetRid: wasi-wasm
+ platform: wasi_wasm_win
+ shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
+ jobParameters:
+ hostedOs: windows
+ runtimeFlavor: ${{ parameters.runtimeFlavor }}
+ stagedBuild: ${{ parameters.stagedBuild }}
+ buildConfig: ${{ parameters.buildConfig }}
+ ${{ insert }}: ${{ parameters.jobParameters }}
+
# Browser WebAssembly
- ${{ if containsValue(parameters.platforms, 'browser_wasm') }}:
diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml
index dfc447572863f..380a217e1b7e5 100644
--- a/eng/pipelines/common/templates/wasm-library-tests.yml
+++ b/eng/pipelines/common/templates/wasm-library-tests.yml
@@ -1,6 +1,5 @@
parameters:
alwaysRun: false
- buildAndRunWasi: false
extraBuildArgs: ''
extraHelixArgs: ''
isExtraPlatformsBuild: false
diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
index 1fff116909b81..29ae803f2bb80 100644
--- a/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
+++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
@@ -9,6 +9,7 @@ parameters:
isRollingBuild: false
excludeLibTests: false
excludeNonLibTests: false
+ excludeOptional: true
debuggerTestsOnly: false
jobs:
@@ -230,3 +231,13 @@ jobs:
#parameters:
#runProfile: 'v8'
#onlySanityCheck: true
+
+- ${{ if and(ne(parameters.isRollingBuild, true), ne(parameters.excludeOptional, true)) }}:
+ - template: /eng/pipelines/common/templates/wasm-library-tests.yml
+ parameters:
+ platforms:
+ - wasi_wasm
+ extraBuildArgs: /p:EnableAggressiveTrimming=true
+ alwaysRun: ${{ parameters.isWasmOnlyBuild }}
+ scenarios:
+ - normal
diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml
index 734530b9b6889..505d78f0a8cd6 100644
--- a/eng/pipelines/libraries/helix-queues-setup.yml
+++ b/eng/pipelines/libraries/helix-queues-setup.yml
@@ -196,7 +196,7 @@ jobs:
- (Ubuntu.1804.Amd64)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly
# Browser WebAssembly windows
- - ${{ if eq(parameters.platform, 'browser_wasm_win') }}:
+ - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}:
- (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly
${{ insert }}: ${{ parameters.jobParameters }}
diff --git a/eng/pipelines/runtime-wasm-optional.yml b/eng/pipelines/runtime-wasm-optional.yml
new file mode 100644
index 0000000000000..86840d3e35db9
--- /dev/null
+++ b/eng/pipelines/runtime-wasm-optional.yml
@@ -0,0 +1,29 @@
+# This is a wrapper yml for `extra-platforms/runtime-extra-platforms-wasm.yml`, which
+# has all the wasm jobs. This file is essentially so we can have point
+# the pipeline in azdo UI to this, and thus avoid any scheduled triggers
+
+trigger: none
+
+variables:
+ - template: /eng/pipelines/common/variables.yml
+
+extends:
+ template: /eng/pipelines/common/templates/pipeline-with-resources.yml
+ parameters:
+ stages:
+ - stage: Build
+ jobs:
+
+ #
+ # Evaluate paths
+ #
+ - template: /eng/pipelines/common/evaluate-default-paths.yml
+
+ - template: /eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
+ parameters:
+ isExtraPlatformsBuild: ${{ variables.isExtraPlatformsBuild }}
+ isWasmOnlyBuild: ${{ variables.isWasmOnlyBuild }}
+ isRollingBuild: ${{ variables.isRollingBuild }}
+ excludeLibTests: true
+ excludeNonLibTests: true
+ excludeOptional: false
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 7e2690fc82fd8..d37e3641de44a 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -373,7 +373,6 @@ extends:
parameters:
platforms:
- browser_wasm
- buildAndRunWasi: true
alwaysRun: ${{ variables.isRollingBuild }}
scenarios:
- normal
@@ -456,12 +455,19 @@ extends:
extraBuildArgs: /p:MonoWasmBuildVariant=perftrace
alwaysRun: ${{ variables.isRollingBuild }}
- # BUILD ONLY - WASI/Wasm
- - template: /eng/pipelines/common/templates/wasi-build-only.yml
+ # WASI/WASM
+
+ - template: /eng/pipelines/common/templates/wasm-library-tests.yml
parameters:
platforms:
- wasi_wasm
+ - wasi_wasm_win
+ nameSuffix: '_Smoke'
+ extraBuildArgs: /p:EnableAggressiveTrimming=true /p:RunWasmSamples=true
+ shouldRunSmokeOnly: true
alwaysRun: ${{ variables.isRollingBuild }}
+ scenarios:
+ - normal
#
# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
diff --git a/eng/testing/WasiRunnerTemplate.cmd b/eng/testing/WasiRunnerTemplate.cmd
new file mode 100644
index 0000000000000..9020bad62bad9
--- /dev/null
+++ b/eng/testing/WasiRunnerTemplate.cmd
@@ -0,0 +1,69 @@
+@echo off
+setlocal enabledelayedexpansion
+
+:: SetCommands defined in eng\testing\tests.wasi.targets
+[[SetCommands]]
+[[SetCommandsEcho]]
+
+set EXECUTION_DIR=%~dp0
+if [%3] NEQ [] (
+ set SCENARIO=%3
+)
+
+if [%HELIX_WORKITEM_UPLOAD_ROOT%] == [] (
+ set "XHARNESS_OUT=%EXECUTION_DIR%xharness-output"
+) else (
+ set "XHARNESS_OUT=%HELIX_WORKITEM_UPLOAD_ROOT%\xharness-output"
+)
+
+if [%XHARNESS_CLI_PATH%] NEQ [] (
+ :: When running in CI, we only have the .NET runtime available
+ :: We need to call the XHarness CLI DLL directly via dotnet exec
+ set HARNESS_RUNNER=dotnet.exe exec "%XHARNESS_CLI_PATH%"
+) else (
+ set HARNESS_RUNNER=dotnet.exe xharness
+)
+
+if [%XHARNESS_COMMAND%] == [] (
+ set XHARNESS_COMMAND=test
+)
+
+if [%XHARNESS_ARGS%] == [] (
+ set "XHARNESS_ARGS=%ENGINE_ARGS%"
+)
+
+if [%PREPEND_PATH%] NEQ [] (
+ set "PATH=%PREPEND_PATH%:%PATH%"
+)
+
+if [%XUNIT_RANDOM_ORDER_SEED%] NEQ [] (
+ set "WasmXHarnessMonoArgs=%WasmXHarnessMonoArgs% --setenv=XUNIT_RANDOM_ORDER_SEED=%XUNIT_RANDOM_ORDER_SEED%"
+)
+
+echo EXECUTION_DIR=%EXECUTION_DIR%
+echo SCENARIO=%SCENARIO%
+echo XHARNESS_OUT=%XHARNESS_OUT%
+echo XHARNESS_CLI_PATH=%XHARNESS_CLI_PATH%
+echo HARNESS_RUNNER=%HARNESS_RUNNER%
+echo XHARNESS_COMMAND=%XHARNESS_COMMAND%
+echo XHARNESS_ARGS=%XHARNESS_ARGS%
+
+:: ========================= BEGIN Test Execution =============================
+echo ----- start %DATE% %TIME% =============== To repro directly: =====================================================
+echo pushd %EXECUTION_DIR%
+:: RunCommands defined in eng\testing\tests.wasi.targets
+[[RunCommandsEcho]]
+echo popd
+echo ===========================================================================================================
+pushd %EXECUTION_DIR%
+@echo on
+:: RunCommands defined in eng\testing\tests.wasi.targets
+[[RunCommands]]
+set EXIT_CODE=%ERRORLEVEL%
+@echo off
+popd
+echo ----- end %DATE% %TIME% ----- exit code %EXIT_CODE% ----------------------------------------------------------
+
+echo XHarness artifacts: %XHARNESS_OUT%
+
+exit /b %EXIT_CODE%
diff --git a/eng/testing/WasiRunnerTemplate.sh b/eng/testing/WasiRunnerTemplate.sh
new file mode 100644
index 0000000000000..b2b9240221031
--- /dev/null
+++ b/eng/testing/WasiRunnerTemplate.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+
+# SetCommands defined in eng\testing\tests.wasi.targets
+[[SetCommands]]
+[[SetCommandsEcho]]
+
+EXECUTION_DIR=$(dirname $0)
+if [[ -n "$3" ]]; then
+ SCENARIO=$3
+fi
+
+if [[ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]]; then
+ XHARNESS_OUT="$EXECUTION_DIR/xharness-output"
+else
+ XHARNESS_OUT="$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output"
+fi
+
+if [[ -n "$XHARNESS_CLI_PATH" ]]; then
+ # When running in CI, we only have the .NET runtime available
+ # We need to call the XHarness CLI DLL directly via dotnet exec
+ HARNESS_RUNNER="dotnet exec $XHARNESS_CLI_PATH"
+else
+ HARNESS_RUNNER="dotnet xharness"
+fi
+
+if [[ -z "$XHARNESS_COMMAND" ]]; then
+ XHARNESS_COMMAND="test"
+fi
+
+if [[ -z "$XHARNESS_ARGS" ]]; then
+ XHARNESS_ARGS="$ENGINE_ARGS"
+fi
+
+if [[ -n "$PREPEND_PATH" ]]; then
+ export PATH=$PREPEND_PATH:$PATH
+fi
+
+if [[ -n "$XUNIT_RANDOM_ORDER_SEED" ]]; then
+ WasmXHarnessMonoArgs="${WasmXHarnessMonoArgs} --setenv=XUNIT_RANDOM_ORDER_SEED=${XUNIT_RANDOM_ORDER_SEED}"
+fi
+
+echo EXECUTION_DIR=$EXECUTION_DIR
+echo SCENARIO=$SCENARIO
+echo XHARNESS_OUT=$XHARNESS_OUT
+echo XHARNESS_CLI_PATH=$XHARNESS_CLI_PATH
+echo HARNESS_RUNNER=$HARNESS_RUNNER
+echo XHARNESS_COMMAND=$XHARNESS_COMMAND
+echo XHARNESS_ARGS=$XHARNESS_ARGS
+
+pushd $EXECUTION_DIR
+
+# ========================= BEGIN Test Execution =============================
+echo ----- start $(date) =============== To repro directly: =====================================================
+echo pushd $EXECUTION_DIR
+# RunCommands defined in eng\testing\tests.wasi.targets
+[[RunCommandsEcho]]
+echo popd
+echo ===========================================================================================================
+pushd $EXECUTION_DIR
+# RunCommands defined in eng\testing\tests.wasi.targets
+[[RunCommands]]
+_exitCode=$?
+popd
+echo ----- end $(date) ----- exit code $_exitCode ----------------------------------------------------------
+
+echo "XHarness artifacts: $XHARNESS_OUT"
+
+exit $_exitCode
diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets
new file mode 100644
index 0000000000000..80cd51f997008
--- /dev/null
+++ b/eng/testing/tests.browser.targets
@@ -0,0 +1,344 @@
+
+
+
+
+ true
+ true
+ false
+ $(BundleTestAppTargets);BundleTestWasmApp
+ true
+
+
+ $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'emsdk'))
+
+
+ true
+
+
+ false
+ true
+
+
+ <_ShellCommandSeparator Condition="'$(OS)' == 'Windows_NT'">&&
+ <_ShellCommandSeparator Condition="'$(OS)' != 'Windows_NT'">&&
+ <_WasmMainJSFileName Condition="'$(WasmMainJSPath)' != ''">$([System.IO.Path]::GetFileName('$(WasmMainJSPath)'))
+ <_WasmStrictVersionMatch Condition="'$(ContinuousIntegrationBuild)' == 'true'">true
+ true
+ <_UseWasmSymbolicator Condition="'$(TestTrimming)' != 'true'">true
+ true
+ false
+ true
+ <_XHarnessTestsTimeout>00:30:00
+
+
+
+
+
+
+
+ true
+
+ $(NoWarn);IL2118
+
+ $(NoWarn);IL2121
+
+
+
+ helix
+ helix
+ local
+
+ <_WasmBrowserPathForTests Condition="'$(BROWSER_PATH_FOR_TESTS)' != ''">$(BROWSER_PATH_FOR_TESTS)
+ <_WasmBrowserPathForTests Condition="'$(_WasmBrowserPathForTests)' == '' and '$(InstallChromeForTests)' == 'true'">$(ChromeBinaryPath)
+
+
+
+ <_AOT_InternalForceInterpretAssemblies Include="@(HighAotMemoryUsageAssembly)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(Scenario)' != 'BuildWasmApps' and '$(WasmMainAssemblyFileName)' == ''">--run WasmTestRunner.dll $(AssemblyName).dll
+ <_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(WasmMainAssemblyFileName)' != ''">--run $(WasmMainAssemblyFileName)
+ <_AppArgs Condition="'$(IsFunctionalTest)' == 'true'">--run $(AssemblyName).dll
+
+ <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs)
+
+ $(WasmXHarnessMonoArgs) --setenv=XHARNESS_LOG_TEST_START=1
+
+
+
+ <_XHarnessArgs Condition="'$(OS)' != 'Windows_NT'">wasm $XHARNESS_COMMAND --app=. --output-directory=$XHARNESS_OUT
+ <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT'">wasm %XHARNESS_COMMAND% --app=. --output-directory=%XHARNESS_OUT%
+
+ <_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)
+ <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)
+ <_XHarnessArgs Condition="('$(WasmEnableThreads)' == 'true' or '$(WasmEnablePerfTracing)' == 'true') and '$(_XHarnessArs.Contains("--web-server-use-cop")' != 'true'">$(_XHarnessArgs) --web-server-use-cop
+ <_XHarnessArgs >$(_XHarnessArgs) -s dotnet.js.symbols
+ <_XHarnessArgs Condition="'$(_UseWasmSymbolicator)' == 'true'" >$(_XHarnessArgs) --symbol-patterns wasm-symbol-patterns.txt
+ <_XHarnessArgs Condition="'$(_UseWasmSymbolicator)' == 'true'" >$(_XHarnessArgs) --symbolicator WasmSymbolicator.dll,Microsoft.WebAssembly.Internal.SymbolicatorWrapperForXHarness
+ <_XHarnessArgs Condition="'$(_WasmBrowserPathForTests)' != ''" >$(_XHarnessArgs) "--browser-path=$(_WasmBrowserPathForTests)"
+ <_XHarnessArgs Condition="'$(_XHarnessTestsTimeout)' != '' " >$(_XHarnessArgs) "--timeout=$(_XHarnessTestsTimeout)"
+ <_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli)
+
+
+ $HARNESS_RUNNER $(_XHarnessArgs) %24XHARNESS_ARGS %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs
+ %HARNESS_RUNNER% $(_XHarnessArgs) %XHARNESS_ARGS% %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs%
+
+
+
+ <_AOTBuildCommand Condition="'$(BrowserHost)' != 'windows'">_buildAOTFunc publish/ProxyProjectForAOTOnHelix.proj $XHARNESS_OUT/AOTBuild.binlog
+ <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">dotnet msbuild publish/ProxyProjectForAOTOnHelix.proj /bl:%XHARNESS_OUT%/AOTBuild.binlog
+
+ <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">$(_AOTBuildCommand) "/p:WasmCachePath=%USERPROFILE%\.emscripten-cache"
+
+
+ <_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration)
+
+ <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation)
+ <_AOTBuildCommand>$(_AOTBuildCommand) $(_ShellCommandSeparator) cd wasm_build/AppBundle
+
+ $(_AOTBuildCommand)
+ $(_AOTBuildCommand) $(_ShellCommandSeparator) $(RunScriptCommand)
+
+
+
+
+
+
+
+ true
+
+
+
+ PrepareForWasmBuildApp;$(WasmNestedPublishAppDependsOn)
+
+
+
+
+ WasmTriggerPublishApp
+ $(BundleTestWasmAppDependsOn);_BundleAOTTestWasmAppForHelix
+
+
+ <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(BundleDir), 'WasmTestRunner.runtimeconfig.json'))
+ exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) $(StartArguments) $(WasmXHarnessMonoArgs) $(_AppArgs)
+
+
+
+
+
+
+
+ true
+
+
+
+ PrepareForWasmBuildApp;$(WasmNestedPublishAppDependsOn)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ -O2
+
+
+
+ <_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == $(AssemblyName) and '%(WasmAssembliesToBundle.Extension)' == '.dll'">%(WasmAssembliesToBundle.Identity)
+ $([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
+ -Oz -Wl,-O0 -Wl,-lto-O0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BundlePdbFiles Include="$([System.IO.Path]::ChangeExtension('%(WasmAssembliesToBundle.Identity)', '.pdb'))" />
+
+
+
+
+
+ <_WasmPropertyNames Include="AOTMode" />
+ <_WasmPropertyNames Include="AssemblyName" />
+ <_WasmPropertyNames Include="DisableParallelAot" />
+ <_WasmPropertyNames Include="DisableParallelEmccCompile" />
+ <_WasmPropertyNames Include="EmccCompileOptimizationFlag" />
+ <_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
+ <_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
+ <_WasmPropertyNames Include="InvariantGlobalization" />
+ <_WasmPropertyNames Include="WasmBuildNative" />
+ <_WasmPropertyNames Include="WasmDebugLevel" />
+ <_WasmPropertyNames Include="WasmDedup" />
+ <_WasmPropertyNames Include="WasmLinkIcalls" />
+ <_WasmPropertyNames Include="WasmNativeStrip" />
+ <_WasmPropertyNames Include="_WasmDevel" />
+ <_WasmPropertyNames Include="_WasmStrictVersionMatch" />
+ <_WasmPropertyNames Include="WasmEmitSymbolMap" />
+
+ <_WasmPropertiesToPass
+ Include="$(%(_WasmPropertyNames.Identity))"
+ Name="%(_WasmPropertyNames.Identity)"
+ ConditionToUse__="%(_WasmPropertyNames.ConditionToUse__)" />
+
+ <_WasmVFSFilesToCopy Include="@(WasmFilesToIncludeInFileSystem)" />
+ <_WasmVFSFilesToCopy TargetPath="%(FileName)%(Extension)" Condition="'%(_WasmVFSFilesToCopy.TargetPath)' == ''" />
+
+ <_WasmExtraFilesToCopy Include="@(WasmExtraFilesToDeploy)" />
+ <_WasmExtraFilesToCopy TargetPath="%(FileName)%(Extension)" Condition="'%(_WasmExtraFilesToCopy.TargetPath)' == ''" />
+
+
+
+ <_WasmItemsToPass Include="@(_AOT_InternalForceInterpretAssemblies)" OriginalItemName__="_AOT_InternalForceInterpretAssemblies" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(BundleDir)
+ WasmTestRunner.dll
+ $(MonoProjectRoot)\wasm\test-main.js
+ $(InvariantGlobalization)
+ true
+
+ true
+ -1
+
+
+
+ <_SatelliteAssemblies Include="$(PublishDir)*\*.resources.dll" />
+ <_SatelliteAssemblies CultureName="$([System.IO.Directory]::GetParent('%(Identity)').Name)" />
+ <_SatelliteAssemblies TargetPath="%(CultureName)\%(FileName)%(Extension)" />
+
+
+
+
+
+
+
+
+ <_CopyLocalPaths
+ Include="@(PublishItemsOutputGroupOutputs)"
+ Condition="'%(PublishItemsOutputGroupOutputs.BuildReference)' == 'true' and
+ !$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.resources.dll'))" />
+
+ <_CopyLocalPaths TargetPath="%(_CopyLocalPaths.RelativePath)" Condition="'%(_CopyLocalPaths.RelativePath)' != ''" />
+ <_CopyLocalPaths TargetPath="%(FileName)%(Extension)" Condition="'%(_CopyLocalPaths.RelativePath)' == ''" />
+
+
+
+
+
+
+
+
+
+
+ <_PdbFilesToCheck Include="$([System.IO.Path]::ChangeExtension('%(ResolvedFileToPublish.Identity)', '.pdb'))"
+ Condition="'%(ResolvedFileToPublish.Extension)' == '.dll'" />
+
+
+
+
+
+
+
+
+
+ <_NodeNpmModuleString Include="%(NodeNpmModule.Identity):%(NodeNpmModule.Alias)" />
+ <_NodeNpmModuleStringTrimmed Include="@(_NodeNpmModuleString->Trim(':'))" />
+
+
+ @(_NodeNpmModuleStringTrimmed, ',')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 01cd9b32fc898..a5c04745736d9 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -78,8 +78,10 @@
Condition="'$(TargetOS)' == 'android'" />
-
+
<_MobileIntermediateOutputPath>$(IntermediateOutputPath)mobile
@@ -133,7 +135,7 @@
<_runnerFilesToPublish Include="$(AndroidTestRunnerDir)*" Condition="'$(TargetOS)' == 'android'" />
<_runnerFilesToPublish Include="$(AppleTestRunnerDir)*" Condition="'$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'tvossimulator'" />
- <_runnerFilesToPublish Include="$(WasmTestRunnerDir)*" Condition="'$(TargetOS)' == 'browser'" />
+ <_runnerFilesToPublish Include="$(WasmTestRunnerDir)*" Condition="'$(TargetOS)' == 'Browser' or '$(TargetOS)' == 'wasi'" />
<_resolvedFilesToPublishToFileName Include="@(ResolvedFileToPublish -> '%(FileName)%(Extension)')" />
diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets
index 0d1bb2c063722..1677d0f4c328d 100644
--- a/eng/testing/tests.targets
+++ b/eng/testing/tests.targets
@@ -9,6 +9,9 @@
AppleHelixRunnerTemplate.sh
AppleRunnerTemplate.sh
AndroidRunnerTemplate.sh
+ WasiRunnerAOTTemplate.sh
+ WasiRunnerTemplate.sh
+ WasiRunnerTemplate.cmd
WasmRunnerAOTTemplate.sh
WasmRunnerTemplate.sh
WasmRunnerTemplate.cmd
@@ -23,7 +26,7 @@
RunTests.sh
build-apple-app.sh
- RunTests.cmd
+ RunTests.cmd
$(AssemblyName).sh
$([MSBuild]::NormalizePath('$(OutDir)', '$(RunScriptOutputName)'))
$([MSBuild]::NormalizePath('$(OutDir)', '$(InnerRunScriptOutputName)'))
@@ -63,12 +66,12 @@
-
+
@@ -78,7 +81,7 @@
<_ZipSourceDirectory>$(OutDir)
- <_ZipSourceDirectory Condition="'$(TargetOS)' == 'browser' or '$(TestSingleFile)' == 'true'">$(BundleDir)
+ <_ZipSourceDirectory Condition="'$(TargetOS)' == 'browser' or '$(TargetOS)' == 'wasi' or '$(TestSingleFile)' == 'true'">$(BundleDir)
@@ -94,8 +97,8 @@
- $(RunScriptCommand) $RSP_FILE
- $(RunScriptCommand) %RSP_FILE%
+ $(RunScriptCommand) $RSP_FILE
+ $(RunScriptCommand) %RSP_FILE%
$([MSBuild]::Escape('$(RunScriptCommand)'))
diff --git a/eng/testing/tests.wasi.targets b/eng/testing/tests.wasi.targets
new file mode 100644
index 0000000000000..8f9a08b576899
--- /dev/null
+++ b/eng/testing/tests.wasi.targets
@@ -0,0 +1,293 @@
+
+
+
+
+
+ true
+ true
+ false
+ $(BundleTestAppTargets);BundleTestWasmApp
+ true
+
+
+ true
+
+
+ false
+ true
+ true
+
+ WasmTestRunner.dll
+
+
+ <_ShellCommandSeparator Condition="'$(OS)' == 'Windows_NT'">&&
+ <_ShellCommandSeparator Condition="'$(OS)' != 'Windows_NT'">&&
+ true
+ <_UseWasmSymbolicator Condition="'$(TestTrimming)' != 'true'">true
+ true
+ false
+ _GetWorkloadsToInstall;$(InstallWorkloadUsingArtifactsDependsOn)
+ <_XHarnessTestsTimeout>00:30:00
+
+ $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasi', 'wasi-sdk'))
+
+
+
+
+
+
+
+ true
+
+ $(NoWarn);IL2118
+
+ $(NoWarn);IL2121
+
+
+
+ helix
+ helix
+ local
+
+
+
+ <_AOT_InternalForceInterpretAssemblies Include="@(HighAotMemoryUsageAssembly)" />
+
+
+
+ <_AppArgs Condition="'$(WasmSingleFileBundle)' == 'true'">$([System.IO.Path]::GetFileNameWithoutExtension('$(WasmMainAssemblyFileName)')).wasm
+ <_AppArgs Condition="'$(WasmSingleFileBundle)' != 'true'">dotnet.wasm
+
+ <_AppArgs Condition="'$(IsFunctionalTest)' != 'true'">$(_AppArgs) $(AssemblyName).dll
+ <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) -- $(WasmTestAppArgs)
+
+
+ $(WasmXHarnessMonoArgs) --env=XHARNESS_LOG_TEST_START=1
+
+
+
+ <_XHarnessArgs Condition="'$(OS)' != 'Windows_NT'">wasi $XHARNESS_COMMAND --app=. --output-directory=$XHARNESS_OUT
+ <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT'">wasi %XHARNESS_COMMAND% --app=. --output-directory=%XHARNESS_OUT%
+
+
+ <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT' and '$(ContinuousIntegrationBuild)' != 'true'">$(_XHarnessArgs) --wasm-engine-path=$(WasmtimeDir)wasmtime.exe
+ <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT' and '$(ContinuousIntegrationBuild)' == 'true'">$(_XHarnessArgs) --wasm-engine-path=%HELIX_CORRELATION_PAYLOAD%\wasmtime\wasmtime.exe
+
+ <_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)
+ <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)
+ <_XHarnessArgs Condition="'$(_XHarnessTestsTimeout)' != '' " >$(_XHarnessArgs) "--timeout=$(_XHarnessTestsTimeout)"
+ <_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli)
+
+
+ $HARNESS_RUNNER $(_XHarnessArgs) %24XHARNESS_ARGS %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs
+ %HARNESS_RUNNER% $(_XHarnessArgs) %XHARNESS_ARGS% %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs%
+
+
+
+ <_AOTBuildCommand Condition="'$(BrowserHost)' != 'windows'">_buildAOTFunc publish/ProxyProjectForAOTOnHelix.proj $XHARNESS_OUT/AOTBuild.binlog
+ <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">dotnet msbuild publish/ProxyProjectForAOTOnHelix.proj /bl:%XHARNESS_OUT%/AOTBuild.binlog
+
+ <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">$(_AOTBuildCommand) "/p:WasmCachePath=%USERPROFILE%\.emscripten-cache"
+
+
+ <_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration)
+
+ <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation)
+ <_AOTBuildCommand>$(_AOTBuildCommand) $(_ShellCommandSeparator) cd wasm_build/AppBundle
+
+ $(_AOTBuildCommand)
+ $(_AOTBuildCommand) $(_ShellCommandSeparator) $(RunScriptCommand)
+
+
+
+
+
+
+
+
+ WasmTriggerPublishApp
+ $(BundleTestWasmAppDependsOn);_BundleAOTTestWasmAppForHelix
+
+
+ <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(BundleDir), 'WasmTestRunner.runtimeconfig.json'))
+ exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) $(StartArguments) $(WasmXHarnessMonoArgs) $(_AppArgs)
+
+
+
+
+
+
+
+ true
+
+
+
+ PrepareForWasmBuildApp;$(WasmNestedPublishAppDependsOn)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ -O2
+
+
+
+ <_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == $(AssemblyName) and '%(WasmAssembliesToBundle.Extension)' == '.dll'">%(WasmAssembliesToBundle.Identity)
+ $([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
+ -Oz -Wl,-O0 -Wl,-lto-O0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BundlePdbFiles Include="$([System.IO.Path]::ChangeExtension('%(WasmAssembliesToBundle.Identity)', '.pdb'))" />
+
+
+
+
+
+ <_WasmPropertyNames Include="AOTMode" />
+ <_WasmPropertyNames Include="AssemblyName" />
+ <_WasmPropertyNames Include="DisableParallelAot" />
+ <_WasmPropertyNames Include="DisableParallelEmccCompile" />
+ <_WasmPropertyNames Include="EmccCompileOptimizationFlag" />
+ <_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
+ <_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
+ <_WasmPropertyNames Include="InvariantGlobalization" />
+ <_WasmPropertyNames Include="WasmBuildNative" />
+ <_WasmPropertyNames Include="WasmDebugLevel" />
+ <_WasmPropertyNames Include="WasmDedup" />
+ <_WasmPropertyNames Include="WasmLinkIcalls" />
+ <_WasmPropertyNames Include="WasmNativeStrip" />
+ <_WasmPropertyNames Include="_WasmDevel" />
+ <_WasmPropertyNames Include="_WasmStrictVersionMatch" />
+ <_WasmPropertyNames Include="WasmEmitSymbolMap" />
+
+ <_WasmPropertiesToPass
+ Include="$(%(_WasmPropertyNames.Identity))"
+ Name="%(_WasmPropertyNames.Identity)"
+ ConditionToUse__="%(_WasmPropertyNames.ConditionToUse__)" />
+
+ <_WasmVFSFilesToCopy Include="@(WasmFilesToIncludeInFileSystem)" />
+ <_WasmVFSFilesToCopy TargetPath="%(FileName)%(Extension)" Condition="'%(_WasmVFSFilesToCopy.TargetPath)' == ''" />
+
+ <_WasmExtraFilesToCopy Include="@(WasmExtraFilesToDeploy)" />
+ <_WasmExtraFilesToCopy TargetPath="%(FileName)%(Extension)" Condition="'%(_WasmExtraFilesToCopy.TargetPath)' == ''" />
+
+
+
+ <_WasmItemsToPass Include="@(_AOT_InternalForceInterpretAssemblies)" OriginalItemName__="_AOT_InternalForceInterpretAssemblies" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(BundleDir)
+ $(MonoProjectRoot)\wasm\test-main.js
+ $(InvariantGlobalization)
+ true
+
+ true
+ -1
+
+
+
+ <_SatelliteAssemblies Include="$(PublishDir)*\*.resources.dll" />
+ <_SatelliteAssemblies CultureName="$([System.IO.Directory]::GetParent('%(Identity)').Name)" />
+ <_SatelliteAssemblies TargetPath="%(CultureName)\%(FileName)%(Extension)" />
+
+
+
+
+
+
+
+
+ <_CopyLocalPaths
+ Include="@(PublishItemsOutputGroupOutputs)"
+ Condition="'%(PublishItemsOutputGroupOutputs.BuildReference)' == 'true' and
+ !$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.resources.dll'))" />
+
+ <_CopyLocalPaths TargetPath="%(_CopyLocalPaths.RelativePath)" Condition="'%(_CopyLocalPaths.RelativePath)' != ''" />
+ <_CopyLocalPaths TargetPath="%(FileName)%(Extension)" Condition="'%(_CopyLocalPaths.RelativePath)' == ''" />
+
+
+
+
+
+
+
+
+
+
+ <_PdbFilesToCheck Include="$([System.IO.Path]::ChangeExtension('%(ResolvedFileToPublish.Identity)', '.pdb'))"
+ Condition="'%(ResolvedFileToPublish.Extension)' == '.dll'" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets
index f382ff6a13771..6516302093b32 100644
--- a/eng/testing/tests.wasm.targets
+++ b/eng/testing/tests.wasm.targets
@@ -1,16 +1,13 @@
- true
+ true
true
false
$(BundleTestAppTargets);BundleTestWasmApp
true
full
-
- $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'emsdk'))
-
true
@@ -39,11 +36,6 @@
$(BundleDir)
-
-
-
true
@@ -57,111 +49,43 @@
helix
helix
local
-
- <_WasmBrowserPathForTests Condition="'$(BROWSER_PATH_FOR_TESTS)' != ''">$(BROWSER_PATH_FOR_TESTS)
- <_WasmBrowserPathForTests Condition="'$(_WasmBrowserPathForTests)' == '' and '$(InstallChromeForTests)' == 'true'">$(ChromeBinaryPath)
<_AOT_InternalForceInterpretAssemblies Include="@(HighAotMemoryUsageAssembly)" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(Scenario)' != 'BuildWasmApps' and '$(WasmMainAssemblyFileName)' == ''">--run WasmTestRunner.dll $(AssemblyName).dll
- <_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(WasmMainAssemblyFileName)' != ''">--run $(WasmMainAssemblyFileName)
- <_AppArgs Condition="'$(IsFunctionalTest)' == 'true'">--run $(AssemblyName).dll
-
- <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs)
+
+
+
- $(WasmXHarnessMonoArgs) --setenv=XHARNESS_LOG_TEST_START=1
-
+
+
-
- <_XHarnessArgs Condition="'$(OS)' != 'Windows_NT'">wasm $XHARNESS_COMMAND --app=. --output-directory=$XHARNESS_OUT
- <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT'">wasm %XHARNESS_COMMAND% --app=. --output-directory=%XHARNESS_OUT%
-
- <_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)
- <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)
- <_XHarnessArgs Condition="('$(MonoWasmBuildVariant)' == 'multithread' or '$(MonoWasmBuildVariant)' == 'perftrace') and '$(_XHarnessArs.Contains("--web-server-use-cop")' != 'true'">$(_XHarnessArgs) --web-server-use-cop
- <_XHarnessArgs >$(_XHarnessArgs) -s dotnet.js.symbols
- <_XHarnessArgs Condition="'$(_UseWasmSymbolicator)' == 'true'" >$(_XHarnessArgs) --symbol-patterns wasm-symbol-patterns.txt
- <_XHarnessArgs Condition="'$(_UseWasmSymbolicator)' == 'true'" >$(_XHarnessArgs) --symbolicator WasmSymbolicator.dll,Microsoft.WebAssembly.Internal.SymbolicatorWrapperForXHarness
- <_XHarnessArgs Condition="'$(_WasmBrowserPathForTests)' != ''" >$(_XHarnessArgs) "--browser-path=$(_WasmBrowserPathForTests)"
- <_XHarnessArgs Condition="'$(_XHarnessTestsTimeout)' != '' " >$(_XHarnessArgs) "--timeout=$(_XHarnessTestsTimeout)"
- <_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli)
-
-
- $HARNESS_RUNNER $(_XHarnessArgs) %24XHARNESS_ARGS %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs
- %HARNESS_RUNNER% $(_XHarnessArgs) %XHARNESS_ARGS% %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs%
-
-
-
- <_AOTBuildCommand Condition="'$(BrowserHost)' != 'windows'">_buildAOTFunc publish/ProxyProjectForAOTOnHelix.proj $XHARNESS_OUT/AOTBuild.binlog
- <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">dotnet msbuild publish/ProxyProjectForAOTOnHelix.proj /bl:%XHARNESS_OUT%/AOTBuild.binlog
-
- <_AOTBuildCommand Condition="'$(BrowserHost)' == 'windows'">$(_AOTBuildCommand) "/p:WasmCachePath=%USERPROFILE%\.emscripten-cache"
-
-
- <_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration)
-
- <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation)
- <_AOTBuildCommand>$(_AOTBuildCommand) $(_ShellCommandSeparator) cd wasm_build/AppBundle
-
- $(_AOTBuildCommand)
- $(_AOTBuildCommand) $(_ShellCommandSeparator) $(RunScriptCommand)
-
+
+
+
-
-
+
+
+
+
- WasmTriggerPublishApp
- $(BundleTestWasmAppDependsOn);_BundleAOTTestWasmAppForHelix
-
-
- <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(BundleDir), 'WasmTestRunner.runtimeconfig.json'))
- exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) $(StartArguments) $(WasmXHarnessMonoArgs) $(_AppArgs)
+
+
-
- true
-
-
-
- PrepareForWasmBuildApp;$(WasmNestedPublishAppDependsOn)
-
-
-
-
-
-
+
+
+
+
@@ -170,11 +94,6 @@
AssemblyFile="$(WasmBuildTasksAssemblyPath)" />
-
- true
- -O2
-
-
<_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == $(AssemblyName) and '%(WasmAssembliesToBundle.Extension)' == '.dll'">%(WasmAssembliesToBundle.Identity)
$([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
@@ -204,9 +123,6 @@
<_WasmPropertyNames Include="AOTMode" />
<_WasmPropertyNames Include="AssemblyName" />
<_WasmPropertyNames Include="DisableParallelAot" />
- <_WasmPropertyNames Include="DisableParallelEmccCompile" />
- <_WasmPropertyNames Include="EmccCompileOptimizationFlag" />
- <_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
<_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
<_WasmPropertyNames Include="InvariantGlobalization" />
<_WasmPropertyNames Include="WasmBuildNative" />
@@ -253,7 +169,6 @@
$(BundleDir)
- WasmTestRunner.dll
$(MonoProjectRoot)\wasm\test-main.js
$(InvariantGlobalization)
true
@@ -304,41 +219,12 @@
-
-
-
-
- <_NodeNpmModuleString Include="%(NodeNpmModule.Identity):%(NodeNpmModule.Alias)" />
- <_NodeNpmModuleStringTrimmed Include="@(_NodeNpmModuleString->Trim(':'))" />
-
-
- @(_NodeNpmModuleStringTrimmed, ',')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-->
+
+
+
+
+
diff --git a/eng/testing/wasi-provisioning.targets b/eng/testing/wasi-provisioning.targets
index ff5c5e02d5efd..29c82eadd4c92 100644
--- a/eng/testing/wasi-provisioning.targets
+++ b/eng/testing/wasi-provisioning.targets
@@ -1,3 +1,29 @@
-
+
+ <_WasmtimeVersionFile>$(MonoProjectRoot)wasi/wasmtime-version.txt
+ true
+
+
+
+
+
+
+
+
+
+ %(_VersionLines.Identity)
+ https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-linux.tar.xz
+ https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-macos.tar.xz
+ https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-windows.zip
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/testing/workloads-testing.targets b/eng/testing/workloads-testing.targets
index cc7c243c6ba3b..068ed599884a2 100644
--- a/eng/testing/workloads-testing.targets
+++ b/eng/testing/workloads-testing.targets
@@ -23,8 +23,8 @@
<_DefaultPropsForNuGetBuild Include="Configuration=$(Configuration)" />
- <_DefaultPropsForNuGetBuild Include="TargetOS=browser" />
- <_DefaultPropsForNuGetBuild Include="TargetArchitecture=wasm" />
+ <_DefaultPropsForNuGetBuild Include="TargetOS=$(TargetOS)" />
+ <_DefaultPropsForNuGetBuild Include="TargetArchitecture=$(TargetArchitecture)" />
<_DefaultPropsForNuGetBuild Include="ContinuousIntegrationBuild=$(ContinuousIntegrationBuild)" />
@@ -157,7 +157,7 @@
DependsOnTargets="$(InstallWorkloadUsingArtifactsDependsOn)"
Condition="'$(InstallWorkloadForTesting)' == 'true'" />
-
+
<_AOTCrossNuGetPath>$(LibrariesShippingPackagesDir)Microsoft.NETCore.App.Runtime.AOT.$(NETCoreSdkRuntimeIdentifier).Cross.$(RuntimeIdentifier).$(PackageVersionForWorkloadManifests).nupkg
diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index ec204db5d1df4..5f56e0eb0bbea 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -252,6 +252,11 @@
+
+
+
+
+
diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
index 9d81146e977cb..79356fc5306d3 100644
--- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
+++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
@@ -47,8 +47,10 @@ public static partial class PlatformDetection
public static bool Isillumos => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ILLUMOS"));
public static bool IsSolaris => RuntimeInformation.IsOSPlatform(OSPlatform.Create("SOLARIS"));
public static bool IsBrowser => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));
+ public static bool IsWasi => RuntimeInformation.IsOSPlatform(OSPlatform.Create("WASI"));
public static bool IsNotBrowser => !IsBrowser;
- public static bool IsMobile => IsBrowser || IsAppleMobile || IsAndroid;
+ public static bool IsNotWasi => !IsWasi;
+ public static bool IsMobile => IsBrowser || IsWasi || IsAppleMobile || IsAndroid;
public static bool IsNotMobile => !IsMobile;
public static bool IsAppleMobile => IsMacCatalyst || IsiOS || IstvOS;
public static bool IsNotAppleMobile => !IsAppleMobile;
@@ -114,13 +116,13 @@ public static bool IsPrivilegedProcess
public static bool FileCreateCaseSensitive => IsCaseSensitiveOS;
#endif
- public static bool IsThreadingSupported => !IsBrowser;
+ public static bool IsThreadingSupported => !IsBrowser && !IsWasi;
public static bool IsBinaryFormatterSupported => IsNotMobile && !IsNativeAot;
public static bool IsStartingProcessesSupported => !IsiOS && !IstvOS;
public static bool IsSpeedOptimized => !IsSizeOptimized;
- public static bool IsSizeOptimized => IsBrowser || IsAndroid || IsAppleMobile;
+ public static bool IsSizeOptimized => IsBrowser || IsWasi || IsAndroid || IsAppleMobile;
public static bool IsBrowserDomSupported => IsEnvironmentVariableTrue("IsBrowserDomSupported");
public static bool IsBrowserDomSupportedOrNotBrowser => IsNotBrowser || IsBrowserDomSupported;
@@ -147,7 +149,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly()
// Drawing is not supported on non windows platforms in .NET 7.0+.
public static bool IsDrawingSupported => IsWindows && IsNotWindowsNanoServer && IsNotWindowsServerCore;
- public static bool IsAsyncFileIOSupported => !IsBrowser;
+ public static bool IsAsyncFileIOSupported => !IsBrowser && !IsWasi;
public static bool IsLineNumbersSupported => !IsNativeAot;
diff --git a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
index 46a942a0f9cde..1307a18a9eb51 100644
--- a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
+++ b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
@@ -11,6 +11,12 @@ public class SimpleWasmTestRunner : WasmApplicationEntryPoint
{
public static async Task Main(string[] args)
{
+ if (args.Length == 0)
+ {
+ Console.WriteLine ($"No args given");
+ return -1;
+ }
+
var testAssembly = args[0];
var excludedTraits = new List();
var includedTraits = new List();
diff --git a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
index 370dc77ce5c03..2ec882a897084 100644
--- a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
+++ b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
@@ -8,7 +8,7 @@
-->
$(Features.Replace('strict', '')
- true
+ true
diff --git a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
index 3a838f8a275d1..de57ee0ab75e0 100644
--- a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
+++ b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
@@ -2,7 +2,7 @@
0436
$(NetCoreAppCurrent);$(NetFrameworkMinimum)
- true
+ true
diff --git a/src/libraries/System.Collections/tests/System.Collections.Tests.csproj b/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
index b728dc258b5f7..3d64df4f13ee5 100644
--- a/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
+++ b/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
@@ -2,7 +2,7 @@
$(NetCoreAppCurrent)
true
- true
+ true
diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/AssemblyInfo.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/AssemblyInfo.cs
index 9659dd75903a7..d3aede3cb97cf 100644
--- a/src/libraries/System.IO.FileSystem.Watcher/tests/AssemblyInfo.cs
+++ b/src/libraries/System.IO.FileSystem.Watcher/tests/AssemblyInfo.cs
@@ -4,4 +4,4 @@
using System;
using Xunit;
-[assembly: SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.tvOS, "System.IO.FileSystem.Watcher is not supported on Browser/iOS/tvOS")]
+[assembly: SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.Wasi | TestPlatforms.iOS | TestPlatforms.tvOS, "System.IO.FileSystem.Watcher is not supported on Browser/iOS/tvOS")]
diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.Unix.cs
index 9455ff312b307..8a6b74de5fd35 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Guid.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Guid.Unix.cs
@@ -11,11 +11,15 @@ public partial struct Guid
public static unsafe Guid NewGuid()
{
Guid g;
-
+#if !TARGET_WASI
// Guid.NewGuid is often used as a cheap source of random data that are sometimes used for security purposes.
// Windows implementation uses secure RNG to implement it. We use secure RNG for Unix too to avoid subtle security
// vulnerabilities in applications that depend on it. See https://github.com/dotnet/runtime/issues/42752 for details.
Interop.GetCryptographicallySecureRandomBytes((byte*)&g, sizeof(Guid));
+#else
+ // TODOWASI: crypto secure random bytes
+ Interop.GetRandomBytes((byte*)&g, sizeof(Guid));
+#endif
const ushort VersionMask = 0xF000;
const ushort RandomGuidVersion = 0x4000;
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
index cdc2c7f54ffc8..bbe1ad497a9de 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
@@ -334,8 +334,8 @@
-
-
+
+
diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj
index 27c862055389a..6118eb1120e6a 100644
--- a/src/libraries/pretest.proj
+++ b/src/libraries/pretest.proj
@@ -22,16 +22,19 @@
-
+
-
+
+
+
+
+ true
+ wasmtime
+ true
+
+
+ PrepareHelixCorrelationPayload_Wasi;
+ _AddWorkItemsForLibraryTests
+
+
+ $(BuildHelixWorkItemsDependsOn);PrepareForBuildHelixWorkItems_Wasi
+ false
+ false
+ false
+
+
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(IsRunningLibraryTests)
+
+
+ true
+
+
+
+
+
+ true
+
+ true
+ false
+
+
+
+
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasiWorkItem Include="$(TestArchiveRoot)browseronly/**/*.zip" Condition="'$(Scenario)' == 'WasmTestOnBrowser'" />
+
+ %(Identity)
+ $(HelixCommand)
+ $(_workItemTimeout)
+
+
+
+
+
+ <_WasiSampleZipFile Condition="'$(Scenario)' == 'normal' or '$(Scenario)' == ''" Include="$(TestArchiveRoot)runonly/**/*.Console.V8.*.Sample.zip" />
+
+
+ %(Identity)
+ $(HelixCommand)
+ $(_workItemTimeout)
+
+
+ <_DefaultWorkItems Remove="@(_DefaultWorkItems)" />
+ <_DefaultWorkItems Include="$(WorkItemArchiveWildCard)" Exclude="$(HelixCorrelationPayload)" />
+
+
+ %(Identity)
+ $(HelixCommand)
+ $(_workItemTimeout)
+
+
+
+
diff --git a/src/libraries/sendtohelix.proj b/src/libraries/sendtohelix.proj
index 71619fc40466a..a5d1ae7f45b6a 100644
--- a/src/libraries/sendtohelix.proj
+++ b/src/libraries/sendtohelix.proj
@@ -152,7 +152,7 @@
-
+
diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj
index bfb6447e647b6..b2e072c486c84 100644
--- a/src/libraries/sendtohelixhelp.proj
+++ b/src/libraries/sendtohelixhelp.proj
@@ -17,8 +17,9 @@
true
+
-
+
- false
+ false
@@ -93,12 +94,14 @@
+ true
+
SetStressModes_$(Scenario).cmd
- SetStressModes_$(Scenario).sh
+ SetStressModes_$(Scenario).sh
ErrorAndContinue
$(ArtifactsBinDir)\*.Tests\**\coverage.opencover.xml
@@ -404,6 +405,11 @@
+
+
+
+
+
@@ -538,6 +544,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -563,7 +579,8 @@
+ Condition="'$(TestAssemblies)' == 'true'"
+ BuildInParallel="$(BuildTestInParallel)" />
true
-
+
@@ -661,6 +678,12 @@
BuildInParallel="false" />
+
+
+
+
- $([MSBuild]::NormalizeDirectory('$(ArtifactsObjDir)', 'wasi-sdk'))
- $(ProvisionWasiSdkDir.Replace('\', '/'))
- true
- true
+ <_ProvisionWasiSdkDir>$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), 'wasi', 'wasi-sdk'))
+ true
+ $(_ProvisionWasiSdkDir)
+ $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)').Replace('\', '/'))
diff --git a/src/mono/mono.proj b/src/mono/mono.proj
index 23fabbcc0e921..d6a4a8fbdee56 100644
--- a/src/mono/mono.proj
+++ b/src/mono/mono.proj
@@ -45,7 +45,7 @@
$([MSBuild]::NormalizeDirectory('$(MonoObjDir)', 'cross'))
$([MSBuild]::NormalizePath('$(MonoObjCrossDir)', 'config.h'))
true
- true
+ true
$(Compiler)
clang
<_CompilerTargetArch Condition="'$(RealTargetArchitecture)' == ''">$(Platform)
@@ -178,16 +178,15 @@
-
-
@@ -201,7 +200,7 @@
%(_ActualVersionLines.Identity)
%(_ExpectedVersionLines.Identity)
-
@@ -437,6 +436,7 @@
<_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'wasi-wasm-threads', 'native', 'include').Replace('\','/'))$(EscapedQuoteW)"/>
<_MonoCFLAGS Condition="'$(MonoWasmThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'wasi-wasm', 'native', 'include').Replace('\','/'))$(EscapedQuoteW)"/>
+
<_MonoCCOption>CC="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
@@ -591,18 +591,19 @@
<_MonoCMakeConfigureCommand>cmake @(_MonoCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))"
<_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoSkipInitCompiler)' != 'true' and '$(HostOS)' != 'windows'">sh -c 'build_arch="$(_CompilerTargetArch)" compiler="$(MonoCCompiler)" . "$(RepositoryEngineeringCommonDir)native/init-compiler.sh" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)'
<_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(_MonoSkipInitCompiler)' == 'true' and '$(HostOS)' != 'windows'">$(_MonoCCOption) $(_MonoCXXOption) @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)
+ <_MonoCMakeConfigureCommand Condition="'$(TargetsWasi)' == 'true'">$(_MonoCMakeConfigureCommand) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot"
+
<_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeConfigureCommand)
<_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' != 'windows'">bash -c 'source $(EMSDK_PATH)/emsdk_env.sh 2>&1 && emcmake $(_MonoCMakeConfigureCommand)'
<_MonoCMakeConfigureCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && emcmake $(_MonoCMakeConfigureCommand)
-
- <_MonoCMakeConfigureCommand Condition="'$(TargetsWasi)' == 'true'">$(_MonoCMakeConfigureCommand) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot"
+ <_MonoCMakeConfigureCommand Condition="'$(TargetsWasi)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && cmake $(_MonoCMakeConfigureCommand)
<_MonoCMakeBuildCommand>cmake --build . --target install --config $(Configuration)
<_MonoCMakeBuildCommand Condition="'$(MonoVerboseBuild)' == 'true'">$(_MonoCMakeBuildCommand) --verbose
<_MonoCMakeBuildCommand Condition="'$(_MonoUseNinja)' != 'true'">$(_MonoCMakeBuildCommand) --parallel $([System.Environment]::ProcessorCount)
<_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' != 'windows'">@(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand)
<_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand)
- <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(_MonoCMakeBuildCommand)
+ <_MonoCMakeBuildCommand Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(_MonoCMakeBuildCommand)
@@ -806,6 +807,7 @@
+
@@ -1066,5 +1068,4 @@
-
diff --git a/src/mono/mono/metadata/sgen-mono.c b/src/mono/mono/metadata/sgen-mono.c
index 446ddb2c2e65e..ea70608fbf3f1 100644
--- a/src/mono/mono/metadata/sgen-mono.c
+++ b/src/mono/mono/metadata/sgen-mono.c
@@ -234,7 +234,7 @@ sgen_has_critical_method (void)
gboolean
mono_gc_is_critical_method (MonoMethod *method)
{
-#ifdef HOST_WASM
+#if defined(HOST_WASM) || defined(HOST_WASI)
//methods can't be critical under wasm due to the single thread'ness of it
return FALSE;
#else
@@ -2281,7 +2281,7 @@ pin_handle_stack_interior_ptrs (void **ptr_slot, void *user_data)
sgen_conservatively_pin_objects_from (ptr_slot, ptr_slot+1, ud->start_nursery, ud->end_nursery, PIN_TYPE_STACK);
}
-#ifdef HOST_WASM
+#if defined(HOST_WASM) || defined(HOST_WASI)
extern gboolean mono_wasm_enable_gc;
#endif
@@ -2293,7 +2293,7 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
{
scan_area_arg_start = start_nursery;
scan_area_arg_end = end_nursery;
-#ifdef HOST_WASM
+#if defined(HOST_WASM) || defined(HOST_WASI)
//Under WASM we don't scan thread stacks and we can't trust the values we find there either.
if (!mono_wasm_enable_gc)
return;
diff --git a/src/mono/mono/sgen/sgen-gc.c b/src/mono/mono/sgen/sgen-gc.c
index fcb1acce709cd..0bdc7fd852a96 100644
--- a/src/mono/mono/sgen/sgen-gc.c
+++ b/src/mono/mono/sgen/sgen-gc.c
@@ -2737,7 +2737,9 @@ gc_pump_callback (void)
sgen_perform_collection_inner (gc_request.requested_size, gc_request.generation_to_collect, gc_request.reason, TRUE, TRUE);
gc_request.generation_to_collect = 0;
}
+#endif
+#if defined(HOST_BROWSER) || defined(HOST_WASI)
extern gboolean mono_wasm_enable_gc;
#endif
diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt
index 15c1630dec160..69c5a3ccd8ccf 100644
--- a/src/mono/mono/utils/CMakeLists.txt
+++ b/src/mono/mono/utils/CMakeLists.txt
@@ -222,6 +222,8 @@ elseif(TARGET_S390X)
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c")
elseif(TARGET_WASM)
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c")
+elseif(TARGET_WASI)
+set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c")
elseif(TARGET_POWERPC OR TARGET_POWERPC64)
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-ppc.c")
else()
diff --git a/src/mono/mono/utils/mono-threads-wasi.S b/src/mono/mono/utils/mono-threads-wasi.S
index f2669f19d5e9b..6de6429445618 100644
--- a/src/mono/mono/utils/mono-threads-wasi.S
+++ b/src/mono/mono/utils/mono-threads-wasi.S
@@ -1,16 +1,15 @@
-.globl get_wasm_stack_high
-.globl get_wasm_stack_low
+// TODO after https://github.com/llvm/llvm-project/commit/1532be98f99384990544bd5289ba339bca61e15b
+// use __stack_low && __stack_high
-get_wasm_stack_high:
- .functype get_wasm_stack_high () -> (i32)
+.globl get_wasm_data_end
+.globl get_wasm_heap_base
+
+get_wasm_data_end:
+ .functype get_wasm_data_end () -> (i32)
global.get __data_end@GOT
- // TODO after https://github.com/llvm/llvm-project/commit/1532be98f99384990544bd5289ba339bca61e15b
- // global.get __stack_high@GOT
end_function
-get_wasm_stack_low:
- .functype get_wasm_stack_low () -> (i32)
+get_wasm_heap_base:
+ .functype get_wasm_heap_base () -> (i32)
global.get __heap_base@GOT
- // TODO after https://github.com/llvm/llvm-project/commit/1532be98f99384990544bd5289ba339bca61e15b
- // global.get __stack_low@GOT
end_function
diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c
index e2031660baf4d..74cc69825f29f 100644
--- a/src/mono/mono/utils/mono-threads-wasm.c
+++ b/src/mono/mono/utils/mono-threads-wasm.c
@@ -43,24 +43,36 @@ wasm_get_stack_size (void)
#else /* WASI */
+// TODO after https://github.com/llvm/llvm-project/commit/1532be98f99384990544bd5289ba339bca61e15b
+// use __stack_low && __stack_high
// see mono-threads-wasi.S
-uintptr_t get_wasm_stack_high(void);
-uintptr_t get_wasm_stack_low(void);
+uintptr_t get_wasm_heap_base(void);
+uintptr_t get_wasm_data_end(void);
static int
-wasm_get_stack_base (void)
+wasm_get_stack_size (void)
{
- return get_wasm_stack_high();
- // this will need change for multithreading as the stack will allocated be per thread at different addresses
+ /*
+ * | -- increasing address ---> |
+ * | data (data_end)| stack |(heap_base) heap |
+ */
+ size_t heap_base = get_wasm_heap_base();
+ size_t data_end = get_wasm_data_end();
+ size_t max_stack_size = heap_base - data_end;
+
+ g_assert (data_end > 0);
+ g_assert (heap_base > data_end);
+
+ // this is the max available stack size size,
+ // return a 16-byte aligned smaller size
+ return max_stack_size & ~0xF;
}
static int
-wasm_get_stack_size (void)
+wasm_get_stack_base (void)
{
- // keep in sync with src\mono\wasi\wasi.proj stack-size
- return 8388608;
- // TODO after https://github.com/llvm/llvm-project/commit/1532be98f99384990544bd5289ba339bca61e15b
- // return (guint8*)get_wasm_stack_high () - (guint8*)get_wasm_stack_low ();
+ return get_wasm_data_end();
+ // this will need further change for multithreading as the stack will allocated be per thread at different addresses
}
#endif
diff --git a/src/mono/sample/wasi/Directory.Build.targets b/src/mono/sample/wasi/Directory.Build.targets
index 353d73bf2e7cd..ffea4d25b08d8 100644
--- a/src/mono/sample/wasi/Directory.Build.targets
+++ b/src/mono/sample/wasi/Directory.Build.targets
@@ -3,72 +3,19 @@
- true
+ true
+ <_SampleProject Condition="'$(_SampleProject)' == ''">$(MSBuildProjectFile)
+ <_SampleAssembly Condition="'$(_SampleAssembly)' == ''">$(TargetFileName)
+ <_ExeExt Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">.exe
-
-
-
- <_ScriptExt Condition="'$(OS)' == 'Windows_NT'">.cmd
- <_ScriptExt Condition="'$(OS)' != 'Windows_NT'">.sh
- <_Dotnet>$(RepoRoot)dotnet$(_ScriptExt)
- <_AOTFlag Condition="'$(RunAOTCompilation)' != ''">/p:RunAOTCompilation=$(RunAOTCompilation)
- <_SampleProject Condition="'$(_SampleProject)' == ''">$(MSBuildProjectFile)
- <_WasmMainJSFileName>$([System.IO.Path]::GetFileName('$(WasmMainJSPath)'))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- %(_VersionLines.Identity)
- https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-linux.tar.xz
- https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-macos.tar.xz
- https://github.com/bytecodealliance/wasmtime/releases/download/v$(WasmtimeVersion)/wasmtime-v$(WasmtimeVersion)-x86_64-windows.zip
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/mono/sample/wasi/console/Makefile b/src/mono/sample/wasi/console/Makefile
new file mode 100644
index 0000000000000..eae68ce1d83d3
--- /dev/null
+++ b/src/mono/sample/wasi/console/Makefile
@@ -0,0 +1,15 @@
+TOP=../../../../..
+
+include ../wasi.mk
+
+ifneq ($(AOT),)
+override MSBUILD_ARGS+=/p:RunAOTCompilation=true
+endif
+
+ifneq ($(V),)
+DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug
+endif
+
+PROJECT_NAME=Wasi.Console.Sample.csproj
+
+run: run-console
diff --git a/src/mono/sample/wasi/console/Program.cs b/src/mono/sample/wasi/console/Program.cs
index c65033a418ebb..f46e3ce16b21d 100644
--- a/src/mono/sample/wasi/console/Program.cs
+++ b/src/mono/sample/wasi/console/Program.cs
@@ -6,10 +6,12 @@
public class Test
{
- public static int Main()
+ public static int Main(string[] args)
{
Console.WriteLine("");
- Console.WriteLine("Hello World!");
+ Console.WriteLine($"Hello World! Got {args.Length} args");
+ foreach (string arg in args)
+ Console.WriteLine ($"arg: {arg}");
Console.WriteLine("");
return 0;
}
diff --git a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj
index 6811cc3a1aeef..042811854a925 100644
--- a/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj
+++ b/src/mono/sample/wasi/console/Wasi.Console.Sample.csproj
@@ -1,7 +1,6 @@
$(NetCoreAppCurrent)
- false
diff --git a/src/mono/sample/wasi/wasi.mk b/src/mono/sample/wasi/wasi.mk
new file mode 100644
index 0000000000000..a9a937612f8e3
--- /dev/null
+++ b/src/mono/sample/wasi/wasi.mk
@@ -0,0 +1,26 @@
+DOTNET=$(TOP)/dotnet.sh
+
+ifeq ($(V),)
+DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary -bl
+else
+DOTNET_Q_ARGS=--nologo -bl
+endif
+
+CONFIG?=Release
+
+WASM_DEFAULT_BUILD_ARGS?=/p:TargetArchitecture=wasm /p:TargetOS=wasi /p:Configuration=$(CONFIG)
+WASMTIME_PROV_PATH=$(realpath $(TOP)/artifacts/obj/wasmtime/wasmtime)
+
+all: publish
+
+build:
+ $(DOTNET) build $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) $(MSBUILD_ARGS) $(PROJECT_NAME)
+
+publish:
+ $(DOTNET) publish $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) -p:WasmBuildOnlyAfterPublish=true $(MSBUILD_ARGS) $(PROJECT_NAME)
+
+clean:
+ rm -rf bin $(TOP)/artifacts/obj/mono/$(PROJECT_NAME:%.csproj=%)
+
+run-console:
+ cd bin/wasi-wasm/AppBundle && $(WASMTIME_PROV_PATH) run $(PROJECT_NAME:.csproj=.wasm) $(ARGS)
diff --git a/src/mono/wasi/.gitignore b/src/mono/wasi/.gitignore
new file mode 100644
index 0000000000000..c2313f66ee085
--- /dev/null
+++ b/src/mono/wasi/.gitignore
@@ -0,0 +1,2 @@
+wasi-sdk/**
+wasmtime/**
diff --git a/src/mono/wasi/Makefile b/src/mono/wasi/Makefile
new file mode 100644
index 0000000000000..d505e8ace0f15
--- /dev/null
+++ b/src/mono/wasi/Makefile
@@ -0,0 +1,107 @@
+TOP=$(realpath $(CURDIR)/../../..)
+-include Make.config
+
+escape_quote = $(subst ",\",$(1))
+
+ifneq ($(V),)
+MSBUILD_ARGS+=/p:MonoVerboseBuild=true
+MSBUILD_ARGS+=-bl
+endif
+
+DOTNET=$(TOP)/dotnet.sh
+
+CONFIG?=Release
+BINDIR?=$(TOP)/artifacts/bin
+OBJDIR?=$(TOP)/artifacts/obj
+_MSBUILD_WASM_BUILD_ARGS=/p:TargetOS=wasi /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG)
+HELIX_TARGET_QUEUE?=Ubuntu.1804.Amd64.Open
+
+all: build-all
+
+MONO_OBJ_DIR=$(OBJDIR)/mono/wasi.wasm.$(CONFIG)
+BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm
+
+#
+# Helper targets
+#
+
+.PHONY: runtime
+.PHONY: build
+
+build:
+ $(TOP)/build.sh mono+libs.pretest -os wasi -c $(CONFIG) --binaryLog /p:ContinueOnError=false /p:StopOnFirstFailure=true $(MSBUILD_ARGS)
+
+build-all:
+ $(TOP)/build.sh mono+libs+packs -os wasi -c $(CONFIG) --binaryLog /p:ContinueOnError=false /p:StopOnFirstFailure=true $(MSBUILD_ARGS)
+
+runtime:
+ $(TOP)/build.sh mono.runtime+mono.wasiruntime+libs.native+libs.pretest -os wasi -c $(CONFIG) /p:ContinueOnError=false /p:StopOnFirstFailure=true $(MSBUILD_ARGS)
+
+# Rebuild only the mono runtime+cross compiler, don't build dotnet.wasm
+mono-runtime:
+ $(TOP)/build.sh mono.runtime+libs.native+libs.pretest -os wasi -c $(CONFIG) /p:ContinueOnError=false /p:StopOnFirstFailure=true $(MSBUILD_ARGS)
+
+corlib:
+ $(TOP)/build.sh mono.corelib+mono.wasiruntime+libs.pretest -os wasi -c $(CONFIG) /p:ContinueOnError=false /p:StopOnFirstFailure=true $(MSBUILD_ARGS)
+
+test-runner:
+ $(DOTNET) build $(TOP)/src/libraries/Common/tests/WasmTestRunner /p:Configuration=$(CONFIG) $(MSBUILD_ARGS)
+
+app-builder:
+ $(DOTNET) build $(TOP)/src/tasks/WasmAppBuilder
+
+build-tasks:
+ $(DOTNET) build $(TOP)/src/tasks/WasmBuildTasks $(MSBUILD_ARGS)
+
+clean:
+ $(RM) -rf $(BUILDS_OBJ_DIR)
+
+run-tests-%:
+ $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS)
+
+run-build-tests:
+ $(DOTNET) build $(TOP)/src/mono/wasi//Wasi.Build.Tests/ /t:Test /p:Configuration=$(CONFIG) $(MSBUILD_ARGS)
+
+build-debugger-tests-helix:
+ $(DOTNET) build -restore -bl:$(TOP)/artifacts/log/$(CONFIG)/Wasm.Debugger.Tests.binlog \
+ /p:ContinuousIntegrationBuild=true /p:ArchiveTests=true \
+ $(TOP)/src/mono/wasm/debugger/Wasm.Debugger.Tests/Wasm.Debugger.Tests.csproj \
+ $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS)
+
+submit-debugger-tests-helix: build-debugger-tests-helix
+ BUILD_REASON=wasm-test SYSTEM_TEAMPROJECT=public BUILD_REPOSITORY_NAME=dotnet/runtime BUILD_SOURCEBRANCH=main \
+ $(TOP)/eng/common/msbuild.sh --ci -restore $(TOP)/src/libraries/sendtohelix.proj \
+ /p:TestRunNamePrefixSuffix=WasmDebugger /p:HelixBuild=`date "+%Y%m%d.%H%M"` /p:Creator=`whoami` \
+ /bl:$(TOP)/artifacts/log/$(CONFIG)/SendToHelix.binlog -p:HelixTargetQueue=$(HELIX_TARGET_QUEUE) \
+ /p:RuntimeFlavor=mono /p:TargetRuntimeIdentifier= /p:MonoForceInterpreter= /p:TestScope=innerloop \
+ /p:_Scenarios=wasmdebuggertests \
+ $(_MSBUILD_WASM_BUILD_ARGS) \
+ $(MSBUILD_ARGS)
+
+submit-tests-helix:
+ echo "\n** This will submit all the available test zip files to helix **\n"
+ BUILD_REASON=wasm-test SYSTEM_TEAMPROJECT=public BUILD_REPOSITORY_NAME=dotnet/runtime BUILD_SOURCEBRANCH=main \
+ $(TOP)/eng/common/msbuild.sh --ci -restore $(TOP)/src/libraries/sendtohelix.proj \
+ /p:TestRunNamePrefixSuffix=WasiTests /p:HelixBuild=`date "+%Y%m%d.%H%M"` /p:Creator=`whoami` \
+ /bl:$(TOP)/artifacts/log/$(CONFIG)/SendToHelix.binlog -v:n -p:HelixTargetQueue=$(HELIX_TARGET_QUEUE) \
+ /p:RuntimeFlavor=mono /p:TargetRuntimeIdentifier= /p:MonoForceInterpreter= /p:TestScope=innerloop \
+ $(_MSBUILD_WASM_BUILD_ARGS) \
+ $(MSBUILD_ARGS)
+
+run-debugger-tests:
+ rm -f $(TOP)/artifacts/bin/DebuggerTestSuite/x64/Debug/*log; \
+ if [ ! -z "$(TEST_FILTER)" ]; then \
+ $(DOTNET) test $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite $(MSBUILD_ARGS) "-l:trx;LogFileName=DebuggerTestsResults.xml" --results-directory $(TOP)/artifacts/log/$(CONFIG) --filter "Category!=failing&FullyQualifiedName$(TEST_FILTER)" $(TEST_ARGS); \
+ else \
+ $(DOTNET) test $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite $(MSBUILD_ARGS) "-l:trx;LogFileName=DebuggerTestsResults.xml" --results-directory $(TOP)/artifacts/log/$(CONFIG) --filter "Category!=failing" $(TEST_ARGS); \
+ fi
+
+build-dbg-proxy:
+ $(DOTNET) build $(TOP)/src/mono/wasm/debugger/wasiDebugHost $(MSBUILD_ARGS)
+build-dbg-testsuite:
+ $(DOTNET) build $(TOP)/src/mono/wasm/debugger/DebuggerTestSuite $(MSBUILD_ARGS)
+build-app-host:
+ $(DOTNET) build $(TOP)/src/mono/wasm/host $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS)
+
+patch-deterministic:
+ cd emsdk/upstream/emscripten/ && patch -p1 < ../../../runtime/deterministic.diff
diff --git a/src/mono/wasi/build/WasiApp.InTree.props b/src/mono/wasi/build/WasiApp.InTree.props
index 8c119d5413b58..585dddf9454be 100644
--- a/src/mono/wasi/build/WasiApp.InTree.props
+++ b/src/mono/wasi/build/WasiApp.InTree.props
@@ -1,2 +1,23 @@
+
+
+
+
+ AnyCPU
+ false
+ $(NetCoreAppCurrent)
+ $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'wasi-sdk'))
+ false
+ true
+ partial
+ false
+
+
+
+ <_MonoRuntimeComponentDontLink Include="libmono-component-debugger-stub-static.a" />
+
+ <_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" Condition="'$(FeatureWasmPerfTracing)' != 'true' and $(FeatureWasmThreads) != 'true'"/>
+ <_MonoRuntimeComponentDontLink Include="libmono-component-hot_reload-stub-static.a" />
+ <_MonoRuntimeComponentDontLink Include="libmono-component-marshal-ilgen-stub-static.a" />
+
diff --git a/src/mono/wasi/build/WasiApp.InTree.targets b/src/mono/wasi/build/WasiApp.InTree.targets
index 8c119d5413b58..ece3fb2d1a3b5 100644
--- a/src/mono/wasi/build/WasiApp.InTree.targets
+++ b/src/mono/wasi/build/WasiApp.InTree.targets
@@ -1,2 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmMainJSFileName>$([System.IO.Path]::GetFileName('$(WasmMainJSPath)'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_LocalMicrosoftNetCoreAppRuntimePackDir>$([MSBuild]::NormalizeDirectory($(ArtifactsBinDir), 'microsoft.netcore.app.runtime.wasi-wasm', $(Configuration)))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildProjectName)
+
+
+ $(TargetOS).AnyCPU.$(Configuration)
+ $([MSBuild]::NormalizeDirectory($(ArtifactsDir), 'helix'))
+ $([MSBuild]::NormalizeDirectory($(HelixArchiveRoot), 'runonly'))
+ $([MSBuild]::NormalizeDirectory($(HelixArchiveRunOnlyRoot), $(OSPlatformConfig), $(WasmHelixTestAppRelativeDir)))
+ $(OutputPath)$(AssemblyName).zip
+
+
+
+
diff --git a/src/mono/wasi/build/WasiApp.Native.targets b/src/mono/wasi/build/WasiApp.Native.targets
new file mode 100644
index 0000000000000..439b6360393f8
--- /dev/null
+++ b/src/mono/wasi/build/WasiApp.Native.targets
@@ -0,0 +1,592 @@
+
+
+
+
+
+
+
+
+ <_WasiBuildNativeCoreDependsOn>
+ _SetupWasiSdk;
+ _SetWasmBuildNativeDefaults;
+ _PrepareForWasiBuildNative;
+ _GetNativeFilesForLinking;
+ _GenerateManagedToNative;
+ _GenerateAssemblyObjectFiles;
+ _WasiLink;
+
+
+
+
+
+
+
+
+ <_ExeExt Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">.exe
+
+
+
+
+
+
+
+
+ <_MonoComponent Include="hot_reload;debugger" />
+
+
+ <_MonoComponent Include="marshal-ilgen" />
+
+
+
+
+
+
+ <_ToolchainMissingPaths Condition="'$(_ToolchainMissingPaths)' == '' and ('$(WasiClang)' == '' or !Exists('$(WasiClang)'))">%24(WasiClang)=$(WasiClang)
+
+
+
+ <_ToolchainMissingErrorMessage Condition="'$(WASI_SDK_PATH)' == '' and '$(WasiSdkRoot)' == ''">Could not find wasi-sdk. Either set %24(WASI_SDK_PATH), or use workloads to get the sdk.
+ <_IsToolchainMissing Condition="'$(_ToolchainMissingErrorMessage)' != ''">true
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+ true
+
+ true
+
+ false
+
+
+
+
+
+ true
+ true
+ true
+
+
+ false
+
+
+ true
+
+ false
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+ <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm'))
+ <_WasiClangDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp'))
+ <_WasiClangDefaultLinkFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-link.rsp'))
+ false
+ true
+ true
+ $(WasmBuildNative)
+
+ <_WasmICallTablePath>$(_WasmIntermediateOutputPath)icall-table.h
+
+ <_WasmPInvokeTablePath>$(_WasmIntermediateOutputPath)pinvoke-table.h
+ <_WasmInterpToNativeTablePath>$(_WasmIntermediateOutputPath)wasm_m2n_invoke.g.h
+ <_WasmPInvokeHPath>$(_WasmRuntimePackIncludeDir)wasm\pinvoke.h
+ <_DriverGenCPath>$(_WasmIntermediateOutputPath)driver-gen.c
+ false
+ $(DisableParallelAot)
+
+ <_DriverGenCNeeded Condition="'$(_DriverGenCNeeded)' == '' and '$(_WasmShouldAOT)' == 'true'">true
+
+ <_WasmDevel Condition="'$(_WasmDevel)' == '' and '$(WasmBuildNative)' == 'true' and '$(Configuration)' == 'Debug'">true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 52428800
+
+
+
+ <_WasmLinkDependencies Remove="@(_WasmLinkDependencies)" />
+
+
+
+
+
+
+
+
+
+
+ <_WasmCommonIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" />
+ <_WasmCommonIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" />
+ <_WasmCommonIncludePaths Include="$(_WasmRuntimePackIncludeDir)wasm" />
+
+
+
+
+ <_WasmCommonIncludePathsFixedUp Include="$([System.String]::new(%(_WasmCommonIncludePaths.Identity)).Replace('\', '/'))" />
+ <_WasmCommonIncludePaths Remove="@(_WasmCommonIncludePaths)" />
+ <_WasmCommonIncludePaths Include="@(_WasmCommonIncludePathsFixedUp)" />
+
+
+
+ <_WasmCommonCFlags Include="-DGEN_PINVOKE=1" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmPInvokeModules Include="%(_WasmNativeFileForLinking.FileName)" Condition="'%(_WasmNativeFileForLinking.ScanForPInvokes)' != 'false'" />
+
+ <_WasmPInvokeModules Include="libSystem.Native" />
+
+
+
+
+
+
+ <_HasMscorlib Condition="'%(_WasmAssembliesInternal.FileName)%(_WasmAssembliesInternal.Extension)' == 'mscorlib.dll'">true
+ <_MscorlibPath Condition="'$(_HasMscorlib)' != 'true'">$(MicrosoftNetCoreAppRuntimePackRidDir)lib\net8.0\mscorlib.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-wasm.a
+
+
+ <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a
+
+
+
+
+
+
+ <_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" />
+
+ <_WasmNativeFileForLinking
+ Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)*.a"
+ Exclude="@(_MonoRuntimeComponentDontLink->'$(MicrosoftNetCoreAppRuntimePackRidNativeDir)%(Identity)')" />
+ <_WasmNativeFileForLinking Condition="'$(_WasmEHLib)' != ''" Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLib)" />
+ <_WasmNativeFileForLinking Remove="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLibToExclude)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_GetBundledFileSourcePath>$(_WasmIntermediateOutputPath)dotnet_wasi_getbundledfile.c
+
+
+
+
+
+
+
+
+ $(_WasmIntermediateOutputPath)%(WasmBundleFilesWithHashes.Filename)%(WasmBundleFilesWithHashes.Extension).$([System.String]::Copy(%(WasmBundleFilesWithHashes.FileHash)).Substring(0, 8)).o
+
+
+
+
+
+
+
+
+
+ <_WasiObjectFilesForBundle Include="$(_GetBundledFileSourcePath)" />
+ <_WasiObjectFilesForBundle Include="%(WasmBundleFilesWithHashes.ObjectFile)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasiGetEntrypointCFile>$(_WasmIntermediateOutputPath)entrypoint_$(WasmMainAssemblyFileName).c
+
+
+
+
+
+
+
+
+
+ <_WasmRuntimePackSrcFile Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)src/*.c" />
+
+
+
+
+ <_WasiSdkLinkerFlags Include="--initial-memory=$(WasmInitialHeapSize)" />
+
+ <_WasiFilePathForFixup Include="$(_WasiGetEntrypointCFile)" />
+ <_WasiFilePathForFixup Include="@(_WasiObjectFilesForBundle)" />
+ <_WasiFilePathForFixup Include="@(_WasmNativeFileForLinking)" />
+ <_WasiFilePathForFixup Include="@(_WasmRuntimePackSrcFile)" />
+
+ <_WasiSdkClangArgs Condition="'$(OS)' == 'Windows_NT'" Include="$([System.String]::new(%(_WasiFilePathForFixup.Identity)).Replace('\', '/'))" />
+ <_WasiSdkClangArgs Condition="'$(OS)' != 'Windows_NT'" Include="@(_WasiFilePathForFixup)" />
+
+ <_WasiSdkClangArgs Include="@(_WasmCommonCFlags)" />
+
+ <_WasiSdkClangArgs Include=""-I%(_WasmCommonIncludePaths.Identity)"" />
+ <_WasiSdkClangArgs Include="--sysroot="$(WasiSdkRoot.Replace('\', '/'))/share/wasi-sysroot"" />
+ <_WasiSdkClangArgs Include="-I"$(MicrosoftNetCoreAppRuntimePackRidNativeDir.Replace('\', '/'))include"" />
+ <_WasiSdkClangArgs Include="-Wl,--export=malloc,--export=free,--export=__heap_base,--export=__data_end" />
+
+ <_WasiSdkClangArgs Include="-Wl,-z,stack-size=8388608,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman"/>
+ <_WasiSdkClangArgs Include="-Wl,-s" />
+
+ <_WasiSdkClangArgs Include="@(_WasiSdkLinkerFlags -> '-Xlinker %(Identity)', ' ')" />
+
+ <_WasiSdkClangArgs Condition="'@(WasiAfterRuntimeLoadedDeclarations)' != ''"
+ Include="-D WASI_AFTER_RUNTIME_LOADED_DECLARATIONS="@(WasiAfterRuntimeLoadedDeclarations, ' ')"" />
+ <_WasiSdkClangArgs Condition="'@(WasiAfterRuntimeLoadedCalls)' != ''"
+ Include="-D WASI_AFTER_RUNTIME_LOADED_CALLS="@(WasiAfterRuntimeLoadedCalls, ' ')"" />
+ <_WasiSdkClangArgs Include="-o "$(_WasmOutputFileName.Replace('\', '/'))"" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AotInputAssemblies Include="@(_WasmAssembliesInternal)">
+ @(MonoAOTCompilerDefaultAotArguments, ';')
+ @(MonoAOTCompilerDefaultProcessArguments, ';')
+
+
+ <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" />
+
+ <_WasmAOTSearchPaths Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)" />
+ <_WasmAOTSearchPaths Include="$(MicrosoftNetCoreAppRuntimePackRidDir)\lib\net8.0" />
+
+
+
+
+ <_AotInputAssemblies Condition="'%(Filename)' != '' and '@(_AotInputAssemblies->Metadata(`Filename`))' != '' and '@(_AOT_InternalForceInterpretAssemblies->Metadata(`Filename`))' != ''">
+ true
+
+
+
+
+
+ LLVMOnlyInterp
+ <_AOTCompilerCacheFile>$(_WasmIntermediateOutputPath)aot_compiler_cache.json
+
+
+
+
+
+
+ <_WasmDedupAssembly>$(_WasmIntermediateOutputPath)\aot-instances.dll
+
+
+
+
+ <_AotInputAssemblies Include="$(_WasmDedupAssembly)">
+ @(MonoAOTCompilerDefaultAotArguments, ';')
+ @(MonoAOTCompilerDefaultProcessArguments, ';')
+
+
+
+
+
+
+
+
+
+
+ <_BitcodeFile Include="%(_WasmAssembliesInternal.LlvmBitcodeFile)" />
+ <_BitcodeFile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" />
+
+
+ <_WasmAssembliesInternal Include="@(_AotInputAssemblies->WithMetadataValue('AOT_InternalForceToInterpret', 'true'))" />
+
+
+
+
+
+
+ <_WasmStrippedAssembliesPath>$([MSBuild]::NormalizeDirectory($(_WasmIntermediateOutputPath), 'stripped-assemblies'))
+
+
+
+ <_AOTedAssemblies Include="@(_WasmAssembliesInternal)" />
+ <_WasmStrippedAssemblies
+ Include="@(_AOTedAssemblies)"
+ OriginalPath="%(_WasmAssembliesInternal.Identity)" />
+
+
+
+
+
+
+
+
+ <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" />
+ <_WasmAssembliesInternal Include="@(_WasmStrippedAssemblies)" />
+
+
+
diff --git a/src/mono/wasi/build/WasiApp.props b/src/mono/wasi/build/WasiApp.props
new file mode 100644
index 0000000000000..9a063a4d5e92f
--- /dev/null
+++ b/src/mono/wasi/build/WasiApp.props
@@ -0,0 +1,28 @@
+
+
+
+ <_RuntimeIdentifierUsesAppHost>false
+ wasm
+ Browser
+ wasi-wasm
+ true
+ partial
+ _WasiBuildNativeCore
+
+ <_WasmBuildCoreDependsOn>
+ _InitializeCommonProperties;
+ _PrepareForAfterBuild;
+ _BeforeWasmBuildApp;
+ $(WasmBuildNativeTarget);
+ _WasiGenerateAppBundle;
+
+
+ $(_WasmBuildCoreDependsOn)
+
+
+
+ _PrepareForNestedPublish;
+ $(_WasmBuildCoreDependsOn)
+
+
+
diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets
new file mode 100644
index 0000000000000..b6f5d563120cf
--- /dev/null
+++ b/src/mono/wasi/build/WasiApp.targets
@@ -0,0 +1,440 @@
+
+
+
+
+
+
+
+ false
+ false
+ false
+
+
+
+ false
+
+ <_BeforeWasmBuildAppDependsOn />
+
+ true
+ true
+ true
+
+ Build
+
+ Publish
+ <_WasmNestedPublishAppPreTarget Condition="'$(DisableAutoWasmPublishApp)' != 'true'">Publish
+
+ true
+ true
+ true
+ false
+
+
+ false
+ true
+ partial
+
+
+ false
+
+
+ -1
+
+ true
+ true
+
+ true
+ wasmtime
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AppBundleDirForRunCommand Condition="'$(WasmAppDir)' != ''">$(WasmAppDir)
+
+
+ <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">$([System.IO.Path]::Combine($(OutputPath), $(RuntimeIdentifier), 'AppBundle'))
+
+
+ <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' != '' and !$([System.IO.Path]::IsPathRooted($(_AppBundleDirForRunCommand)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_AppBundleDirForRunCommand)))
+
+
+
+ $(DOTNET_HOST_PATH)
+ dotnet
+
+ <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_AppBundleDirForRunCommand), '$(AssemblyName).runtimeconfig.json'))
+ exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments)
+ $(_AppBundleDirForRunCommand)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
+
+
+
+
+
+
+
+
+ <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %(ResolvedRuntimePack.PackageDirectory)
+ $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackDir), 'runtimes', $(RuntimeIdentifier)))
+ $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir)))
+ $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir), 'native'))
+
+ <_WasmRuntimePackIncludeDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include'))
+ <_WasmRuntimePackSrcDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'src'))
+
+ <_WasmIntermediateOutputPath Condition="'$(WasmBuildingForNestedPublish)' == ''">$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm', 'for-build'))
+ <_WasmIntermediateOutputPath Condition="'$(WasmBuildingForNestedPublish)' != ''">$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm', 'for-publish'))
+
+ <_DriverGenCPath>$(_WasmIntermediateOutputPath)driver-gen.c
+ <_WasmShouldAOT Condition="'$(WasmBuildingForNestedPublish)' == 'true' and '$(RunAOTCompilation)' == 'true'">true
+ <_WasmShouldAOT Condition="'$(RunAOTCompilationAfterBuild)' == 'true' and '$(RunAOTCompilation)' == 'true'">true
+ <_WasmShouldAOT Condition="'$(_WasmShouldAOT)' == ''">false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $([MSBuild]::NormalizeDirectory($(OutputPath), 'AppBundle'))
+ $(TargetFileName)
+ <_WasmOutputFileName Condition="'$(WasmSingleFileBundle)' == 'true'">$([System.IO.Path]::GetFileNameWithoutExtension('$(WasmMainAssemblyFileName)')).wasm
+ <_WasmOutputFileName Condition="'$(WasmSingleFileBundle)' != 'true'">dotnet.wasm
+ <_WasmOutputFileName>$([System.IO.Path]::Combine($(_WasmIntermediateOutputPath), $(_WasmOutputFileName)))
+
+ $([MSBuild]::NormalizeDirectory($(WasmAppDir)))
+
+ <_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == $(AssemblyName) and '%(WasmAssembliesToBundle.Extension)' == '.dll' and $(WasmGenerateAppBundle) == 'true'">%(WasmAssembliesToBundle.Identity)
+ <_WasmRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' == '' and $(_MainAssemblyPath) != ''">$([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
+ <_ParsedRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' != ''">$([System.IO.Path]::GetDirectoryName($(_WasmRuntimeConfigFilePath)))\runtimeconfig.bin
+
+
+
+
+
+
+
+ <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" />
+ <_WasmAssembliesInternal Include="@(WasmAssembliesToBundle->Distinct())" WasmRole="assembly" />
+
+ <_WasmSatelliteAssemblies Remove="@(_WasmSatelliteAssemblies)" />
+ <_WasmSatelliteAssemblies Include="@(_WasmAssembliesInternal)" />
+ <_WasmSatelliteAssemblies Remove="@(_WasmSatelliteAssemblies)" Condition="!$([System.String]::Copy('%(Identity)').EndsWith('.resources.dll'))" />
+
+ <_WasmSatelliteAssemblies CultureName="$([System.IO.Directory]::GetParent('%(Identity)').Name)" WasmRole="SatelliteAssembly" />
+
+ <_WasmAssembliesInternal Remove="@(_WasmSatelliteAssemblies)" />
+
+
+
+
+
+ <_RuntimeConfigReservedProperties Include="RUNTIME_IDENTIFIER"/>
+ <_RuntimeConfigReservedProperties Include="APP_CONTEXT_BASE_DIRECTORY"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ icudt.dat
+
+ <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true
+ <_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.worker.js'">true
+ <_HasDotnetJsSymbols Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js.symbols'">true
+ <_HasDotnetJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js'">true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmAppIncludeThreadsWorker Condition="'$(WasmEnableThreads)' == 'true' or '$(WasmEnablePerfTracing)' == 'true'">true
+
+ <_WasmPThreadPoolSize Condition="'$(_WasmPThreadPoolSize)' == '' and ('$(WasmEnableThreads)' == 'true' or '$(WasmEnablePerfTracing)' == 'true')">-1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(WasmAppDir)run-v8.sh
+ <_WasmMainJSFileName>$([System.IO.Path]::GetFileName('$(WasmMainJSPath)'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" />
+ <_WasmAssembliesInternal Include="@(_TmpWasmAssemblies)" />
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/wasi/build/WasiSdk.Defaults.props b/src/mono/wasi/build/WasiSdk.Defaults.props
new file mode 100644
index 0000000000000..51ce6b50a2eff
--- /dev/null
+++ b/src/mono/wasi/build/WasiSdk.Defaults.props
@@ -0,0 +1,7 @@
+
+
+ $(WASI_SDK_PATH)
+ $(WasiSdkRoot)\bin\clang
+ $(WasiClang).exe
+
+
diff --git a/src/mono/wasi/mono-include/driver.h b/src/mono/wasi/mono-include/driver.h
index 664680e137c23..5e1f66825f588 100644
--- a/src/mono/wasi/mono-include/driver.h
+++ b/src/mono/wasi/mono-include/driver.h
@@ -8,7 +8,7 @@
void mono_wasm_load_runtime (const char *unused, int debug_level);
int mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size);
MonoAssembly* mono_wasm_assembly_load(const char *name);
-MonoMethod* mono_wasm_assembly_get_entry_point (MonoAssembly *assembly);
+MonoMethod* mono_wasi_assembly_get_entry_point (MonoAssembly *assembly);
MonoClass* mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name);
MonoMethod* mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments);
MonoObject* mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc);
diff --git a/src/mono/wasi/provision.ps1 b/src/mono/wasi/provision.ps1
index 3d3602f0a901c..9f8d049fdc72d 100644
--- a/src/mono/wasi/provision.ps1
+++ b/src/mono/wasi/provision.ps1
@@ -11,6 +11,6 @@ param(
New-Item -Path $WasiSdkPath -ItemType "directory"
Invoke-WebRequest -Uri $WasiSdkUrl -OutFile ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz
-tar --strip-components=1 -xvzf ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -C $WasiSdkPath
+tar --strip-components=1 -xzf ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -C $WasiSdkPath
Copy-Item $WasiLocalPath/wasi-sdk-version.txt $WasiSdkPath/wasi-sdk-version.txt
Remove-Item ./wasi-sdk-$WasiSdkVersion.0-mingw.tar.gz -fo
diff --git a/src/mono/wasi/runtime/driver.c b/src/mono/wasi/runtime/driver.c
index f460a450c0bd3..2971e0499476a 100644
--- a/src/mono/wasi/runtime/driver.c
+++ b/src/mono/wasi/runtime/driver.c
@@ -35,7 +35,8 @@
#ifdef GEN_PINVOKE
#include "wasm_m2n_invoke.g.h"
#endif
-#include "../../wasm/runtime/gc-common.h"
+#include "gc-common.h"
+#include "driver.h"
#if !defined(ENABLE_AOT) || defined(EE_MODE_LLVMONLY_INTERP)
@@ -63,6 +64,9 @@ int32_t monoeg_g_hasenv(const char *variable);
void mono_free (void*);
int32_t mini_parse_debug_option (const char *option);
char *mono_method_get_full_name (MonoMethod *method);
+extern const char* dotnet_wasi_getbundledfile(const char* name, int* out_length);
+extern void dotnet_wasi_registerbundledassemblies();
+extern const char* dotnet_wasi_getentrypointassemblyname();
int mono_wasm_enable_gc = 1;
@@ -81,7 +85,10 @@ static MonoDomain *root_domain;
static void
wasi_trace_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data)
{
- printf("[wasi_trace_logger] %s\n", message);
+ if (strcmp(log_level, "error") == 0)
+ fprintf(stderr, "[MONO] %s: %s\n", log_level, message);
+ else
+ printf("[MONO] %s: %s\n", log_level, message);
if (fatal) {
// make it trap so we could see the stack trace
// (*(int*)(void*)-1)++;
@@ -107,6 +114,7 @@ static int assembly_count;
int
mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size)
{
+ /*printf("wasi: mono_wasm_add_assembly: %s size: %u\n", name, size);*/
int len = strlen (name);
if (!strcasecmp (".pdb", &name [len - 4])) {
char *new_name = strdup (name);
@@ -542,7 +550,7 @@ mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void
}
MonoMethod*
-mono_wasm_assembly_get_entry_point (MonoAssembly *assembly)
+mono_wasi_assembly_get_entry_point (MonoAssembly *assembly)
{
MonoImage *image;
MonoMethod *method;
@@ -556,43 +564,6 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly)
mono_domain_ensure_entry_assembly (root_domain, assembly);
method = mono_get_method (image, entry, NULL);
- /*
- * If the entry point looks like a compiler generated wrapper around
- * an async method in the form "" then try to look up the async methods
- * "$" and "Name" it could be wrapping. We do this because the generated
- * sync wrapper will call task.GetAwaiter().GetResult() when we actually want
- * to yield to the host runtime.
- */
- if (mono_method_get_flags (method, NULL) & 0x0800 /* METHOD_ATTRIBUTE_SPECIAL_NAME */) {
- const char *name = mono_method_get_name (method);
- int name_length = strlen (name);
-
- if ((*name != '<') || (name [name_length - 1] != '>'))
- goto end;
-
- MonoClass *klass = mono_method_get_class (method);
- assert(klass);
- char *async_name = malloc (name_length + 2);
- snprintf (async_name, name_length + 2, "%s$", name);
-
- // look for "$"
- MonoMethodSignature *sig = mono_method_get_signature (method, image, mono_method_get_token (method));
- MonoMethod *async_method = mono_class_get_method_from_name (klass, async_name, mono_signature_get_param_count (sig));
- if (async_method != NULL) {
- free (async_name);
- method = async_method;
- goto end;
- }
-
- // look for "Name" by trimming the first and last character of ""
- async_name [name_length - 1] = '\0';
- async_method = mono_class_get_method_from_name (klass, async_name + 1, mono_signature_get_param_count (sig));
-
- free (async_name);
- if (async_method != NULL)
- method = async_method;
- }
-
end:
MONO_EXIT_GC_UNSAFE;
return method;
@@ -698,26 +669,43 @@ MonoMethod* lookup_dotnet_method(const char* assembly_name, const char* namespac
return method;
}
-int main() {
+MonoArray*
+mono_wasm_string_array_new (int size)
+{
+ return mono_array_new (root_domain, mono_get_string_class (), size);
+}
+
+#ifdef _WASI_DEFAULT_MAIN
+int main(int argc, char * argv[]) {
+ printf("TODOWASI: default main for non-relinked, non-aot apps, TODO\n");
+ if (argc < 2) {
+ printf("Error: First argument must be the name of the main assembly\n");
+ return 1;
+ }
// Assume the runtime pack has been copied into the output directory as 'runtime'
// Otherwise we have to mount an unrelated part of the filesystem within the WASM environment
- mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net8.0");
+ // AJ: not needed right now as we are bundling all the assemblies in the .wasm
+ mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net7.0");
mono_wasm_load_runtime("", 0);
- MonoAssembly* assembly = mono_wasm_assembly_load ("Wasi.Console.Sample");
- MonoMethod* entry_method = mono_wasm_assembly_get_entry_point (assembly);
+ MonoAssembly* assembly = mono_wasm_assembly_load (argv[1]);
+ if (!assembly) {
+ printf("wasi: mono_wasm_assembly_load returned NULL!\n");
+ return 1;
+ }
+ MonoMethod* entry_method = mono_wasi_assembly_get_entry_point (assembly);
+ if (!entry_method) {
+ fprintf(stderr, "Could not find entrypoint in the assembly.\n");
+ exit(1);
+ }
+
MonoObject* out_exc;
MonoObject* out_res;
- mono_wasm_invoke_method_ref (entry_method, NULL, NULL, &out_exc, &out_res);
- if (out_exc)
- {
+ int ret = mono_runtime_run_main(entry_method, argc, argv, &out_exc);
+ if (out_exc) {
mono_print_unhandled_exception(out_exc);
exit(1);
}
- if(out_res)
- {
- int r= mono_unbox_int (out_res);
- return r;
- }
- return 0;
-}
\ No newline at end of file
+ return ret;
+}
+#endif
diff --git a/src/mono/wasi/runtime/main.c b/src/mono/wasi/runtime/main.c
new file mode 100644
index 0000000000000..2cf4c86186728
--- /dev/null
+++ b/src/mono/wasi/runtime/main.c
@@ -0,0 +1,48 @@
+#include
+#include
+#include
+
+// This symbol's implementation is generated during the build
+const char* dotnet_wasi_getentrypointassemblyname();
+
+// These are generated by EmitWasmBundleObjectFile
+const char* dotnet_wasi_getbundledfile(const char* name, int* out_length);
+void dotnet_wasi_registerbundledassemblies();
+
+#ifdef WASI_AFTER_RUNTIME_LOADED_DECLARATIONS
+// This is supplied from the MSBuild itemgroup @(WasiAfterRuntimeLoaded)
+WASI_AFTER_RUNTIME_LOADED_DECLARATIONS
+#endif
+
+int main(int argc, char * argv[]) {
+ // generated during the build
+ dotnet_wasi_registerbundledassemblies();
+
+#ifdef WASI_AFTER_RUNTIME_LOADED_CALLS
+ // This is supplied from the MSBuild itemgroup @(WasiAfterRuntimeLoaded)
+ WASI_AFTER_RUNTIME_LOADED_CALLS
+#endif
+ // Assume the runtime pack has been copied into the output directory as 'runtime'
+ // Otherwise we have to mount an unrelated part of the filesystem within the WASM environment
+ // AJ: not needed right now as we are bundling all the assemblies in the .wasm
+ /*mono_set_assemblies_path(".:./runtime/native:./runtime/lib/net7.0");*/
+ mono_wasm_load_runtime("", 0);
+
+ const char* assembly_name = dotnet_wasi_getentrypointassemblyname();
+ MonoAssembly* assembly = mono_assembly_open(assembly_name, NULL);
+ MonoMethod* entry_method = mono_wasi_assembly_get_entry_point (assembly);
+ if (!entry_method) {
+ fprintf(stderr, "Could not find entrypoint in assembly %s\n", assembly_name);
+ exit(1);
+ }
+
+ MonoObject* out_exc;
+ MonoObject* out_res;
+ int ret = mono_runtime_run_main(entry_method, argc, argv, &out_exc);
+ if (out_exc)
+ {
+ mono_print_unhandled_exception(out_exc);
+ exit(1);
+ }
+ return ret;
+}
diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj
index 92257ee0187e5..a45ee39654e0f 100644
--- a/src/mono/wasi/wasi.proj
+++ b/src/mono/wasi/wasi.proj
@@ -6,8 +6,9 @@
- $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'wasi-wasm', 'native', 'lib'))
- $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'wasi-wasm-threads', 'native', 'lib'))
+
+
+
false
false
$(ArtifactsObjDir)wasm
@@ -101,8 +102,10 @@
<_WasiCompileFlags Include="-D_WASI_EMULATED_PROCESS_CLOCKS"/>
<_WasiCompileFlags Include="-D_WASI_EMULATED_SIGNAL"/>
<_WasiCompileFlags Include="-D_WASI_EMULATED_MMAN"/>
+ <_WasiCompileFlags Include="-D_WASI_DEFAULT_MAIN"/>
+
- <_WasiLinkFlags Include="-Wl,-z,stack-size=8388608,--initial-memory=52428800,--max-memory=671088640,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman"/>
+ <_WasiLinkFlags Include="-Wl,-z,stack-size=8388608,--initial-memory=52428800,-lwasi-emulated-process-clocks,-lwasi-emulated-signal,-lwasi-emulated-mman"/>
@@ -146,10 +149,10 @@
DependsOnTargets="GenerateWasiPropsAndRspFiles;GenerateManagedToNative;BundleTimeZones">
-
-
+
+
+
+
$(ArtifactsObjDir)wasm/pinvoke-table.h
@@ -187,9 +190,21 @@
-v
cmake --build . --config $(Configuration) $(CmakeOptions)
-
+ call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(CMakeBuildRuntimeCmd)
+
+ <_FilesToCopy Include="$(MSBuildThisFileDirectory)runtime/driver.c" DestinationFolder="$(NativeBinDir)src" />
+ <_FilesToCopy Include="$(MSBuildThisFileDirectory)runtime/main.c" DestinationFolder="$(NativeBinDir)src" />
+ <_FilesToCopy Include="$(MSBuildThisFileDirectory)runtime/pinvoke.c" DestinationFolder="$(NativeBinDir)src" />
+ <_FilesToCopy Include="$(MSBuildThisFileDirectory)runtime/stubs.c" DestinationFolder="$(NativeBinDir)src" />
+ <_FilesToCopy Include="$(MSBuildThisFileDirectory)runtime/synthetic-pthread.c" DestinationFolder="$(NativeBinDir)src" />
+
+ <_FilesToCopy Include="$(MonoProjectRoot)wasi\mono-include\driver.h" DestinationFolder="$(NativeBinDir)include\wasm" />
+ <_FilesToCopy Include="$(MonoProjectRoot)wasi\mono-include\pinvoke.h" DestinationFolder="$(NativeBinDir)include\wasm" />
+ <_FilesToCopy Include="$(MonoProjectRoot)wasm\runtime\gc-common.h" DestinationFolder="$(NativeBinDir)include\wasm" />
+
+
@@ -197,19 +212,10 @@
-
-
-
+
> _filesToBundleByObjectFileName = default!;
+
+ [Required]
+ public ITaskItem[] FilesToBundle { get; set; } = default!;
+
+ [Required]
+ public string ClangExecutable { get; set; } = default!;
+
+ [Output]
+ public string? BundleApiSourceCode { get; set; }
+
+ private static byte[] InitLookupTable()
+ {
+ // Every 6 bytes in this array represents the output for a different input byte value.
+ // For example, the input byte 0x1a (26 decimal) corresponds to bytes 156-161 (26*6=156),
+ // whose values will be ['0', 'x', '1', 'a', ',', ' '], which is the UTF-8 representation
+ // for "0x1a, ". This is just a faster alternative to calling .ToString("x2") on every
+ // byte of the input file and then pushing that string through UTF8Encoding.
+ var lookup = new byte[256 * 6];
+ for (int i = 0; i < 256; i++)
+ {
+ string byteAsHex = i.ToString("x2");
+ char highOrderChar = BitConverter.IsLittleEndian ? byteAsHex[0] : byteAsHex[1];
+ char lowOrderChar = BitConverter.IsLittleEndian ? byteAsHex[1] : byteAsHex[0];
+ lookup[i * 6 + 0] = (byte)'0';
+ lookup[i * 6 + 1] = (byte)'x';
+ lookup[i * 6 + 2] = (byte)highOrderChar;
+ lookup[i * 6 + 3] = (byte)lowOrderChar;
+ lookup[i * 6 + 4] = (byte)',';
+ lookup[i * 6 + 5] = (byte)' ';
+ }
+
+ return lookup;
+ }
+
+ public override bool Execute()
+ {
+ if (!File.Exists(ClangExecutable))
+ {
+ Log.LogError($"Cannot find {nameof(ClangExecutable)}={ClangExecutable}");
+ return false;
+ }
+
+ // The ObjectFile (output filename) already includes a content hash. Grouping by this filename therefore
+ // produces one group per file-content. We only want to emit one copy of each file-content, and one symbol for it.
+ _filesToBundleByObjectFileName = FilesToBundle.GroupBy(f => f.GetMetadata("ObjectFile")).ToList();
+
+ // We're handling the incrementalism within this task, because it needs to be based on file content hashes
+ // and not on timetamps. The output filenames contain a content hash, so if any such file already exists on
+ // disk with that name, we know it must be up-to-date.
+ var remainingObjectFilesToBundle = _filesToBundleByObjectFileName.Where(g => !File.Exists(g.Key)).ToArray();
+
+ // If you're only touching the leaf project, we don't really need to tell you that.
+ // But if there's more work to do it's valuable to show progress.
+ var verbose = remainingObjectFilesToBundle.Length > 1;
+ var verboseCount = 0;
+
+ if (remainingObjectFilesToBundle.Length > 0)
+ {
+ int allowedParallelism = Math.Max(Math.Min(remainingObjectFilesToBundle.Length, Environment.ProcessorCount), 1);
+ if (BuildEngine is IBuildEngine9 be9)
+ allowedParallelism = be9.RequestCores(allowedParallelism);
+
+ Parallel.For(0, remainingObjectFilesToBundle.Length, new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism, CancellationToken = BuildTaskCancelled.Token }, i =>
+ {
+ var objectFile = remainingObjectFilesToBundle[i];
+
+ // Since the object filenames include a content hash, we can pick an arbitrary ITaskItem from each group,
+ // since we know each group's ITaskItems all contain the same binary data
+ var contentSourceFile = objectFile.First();
+
+ var outputFile = objectFile.Key;
+ if (verbose)
+ {
+ var count = Interlocked.Increment(ref verboseCount);
+ Log.LogMessage(MessageImportance.High, "{0}/{1} Bundling {2}...", count, remainingObjectFilesToBundle.Length, Path.GetFileName(contentSourceFile.ItemSpec));
+ }
+
+ EmitObjectFile(contentSourceFile, outputFile);
+ });
+ }
+
+ BundleApiSourceCode = GetBundleFileApiSource(_filesToBundleByObjectFileName);
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private void EmitObjectFile(ITaskItem fileToBundle, string destinationObjectFile)
+ {
+ Log.LogMessage(MessageImportance.Low, "Bundling {0} as {1}", fileToBundle.ItemSpec, destinationObjectFile);
+
+ if (Path.GetDirectoryName(destinationObjectFile) is string destDir && !string.IsNullOrEmpty(destDir))
+ Directory.CreateDirectory(destDir);
+
+ var clangProcess = Process.Start(new ProcessStartInfo
+ {
+ FileName = ClangExecutable,
+ Arguments = $"-xc -o \"{destinationObjectFile}\" -c -",
+ RedirectStandardInput = true,
+ UseShellExecute = false,
+ })!;
+
+ BundleFileToCSource(destinationObjectFile, fileToBundle, clangProcess.StandardInput.BaseStream);
+ clangProcess.WaitForExit();
+ }
+
+ private static string GetBundleFileApiSource(ICollection> bundledFilesByObjectFileName)
+ {
+ // Emit an object file that uses all the bundle file symbols and supplies an API
+ // for getting the bundled file data at runtime
+ var result = new StringBuilder();
+
+ result.AppendLine("#include ");
+ result.AppendLine();
+ result.AppendLine("int mono_wasm_add_assembly(const char* name, const unsigned char* data, unsigned int size);");
+ result.AppendLine();
+
+ foreach (var objectFileGroup in bundledFilesByObjectFileName)
+ {
+ var symbol = ToSafeSymbolName(objectFileGroup.Key);
+ result.AppendLine($"extern const unsigned char {symbol}[];");
+ result.AppendLine($"extern const int {symbol}_len;");
+ }
+
+ result.AppendLine();
+ result.AppendLine("const unsigned char* dotnet_wasi_getbundledfile(const char* name, int* out_length) {");
+
+ // TODO: Instead of a naive O(N) search through all bundled files, consider putting them in a
+ // hashtable or at least generating a series of comparisons equivalent to a binary search
+
+ foreach (var objectFileGroup in bundledFilesByObjectFileName)
+ {
+ foreach (var file in objectFileGroup.Where(f => !string.Equals(f.GetMetadata("WasmRole"), "assembly", StringComparison.OrdinalIgnoreCase)))
+ {
+ var symbol = ToSafeSymbolName(objectFileGroup.Key);
+ result.AppendLine($" if (!strcmp (name, \"{file.ItemSpec.Replace("\\", "/")}\")) {{");
+ result.AppendLine($" *out_length = {symbol}_len;");
+ result.AppendLine($" return {symbol};");
+ result.AppendLine(" }");
+ result.AppendLine();
+ }
+ }
+
+ result.AppendLine(" return NULL;");
+ result.AppendLine("}");
+
+ result.AppendLine();
+ result.AppendLine("void dotnet_wasi_registerbundledassemblies() {");
+
+ foreach (var objectFileGroup in bundledFilesByObjectFileName)
+ {
+ foreach (var file in objectFileGroup.Where(f => string.Equals(f.GetMetadata("WasmRole"), "assembly", StringComparison.OrdinalIgnoreCase)))
+ {
+ var symbol = ToSafeSymbolName(objectFileGroup.Key);
+ result.AppendLine($" mono_wasm_add_assembly (\"{Path.GetFileName(file.ItemSpec)}\", {symbol}, {symbol}_len);");
+ }
+ }
+
+ result.AppendLine("}");
+
+ return result.ToString();
+ }
+
+ private static void BundleFileToCSource(string objectFileName, ITaskItem fileToBundle, Stream outputStream)
+ {
+ // Emits a C source file in the same format as "xxd --include". Example:
+ //
+ // unsigned char Some_File_dll[] = {
+ // 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a
+ // };
+ // unsigned int Some_File_dll_len = 6;
+
+ using var inputStream = File.OpenRead(fileToBundle.ItemSpec);
+ using var outputUtf8Writer = new StreamWriter(outputStream, Utf8NoBom);
+
+ var symbolName = ToSafeSymbolName(objectFileName);
+ outputUtf8Writer.Write($"unsigned char {symbolName}[] = {{");
+ outputUtf8Writer.Flush();
+
+ var buf = new byte[4096];
+ var bytesRead = 0;
+ var generatedArrayLength = 0;
+ var bytesEmitted = 0;
+ while ((bytesRead = inputStream.Read(buf, 0, buf.Length)) > 0)
+ {
+ for (var i = 0; i < bytesRead; i++)
+ {
+ if (bytesEmitted++ % 12 == 0)
+ {
+ outputStream.Write(NewLineAndIndentation, 0, NewLineAndIndentation.Length);
+ }
+
+ var byteValue = buf[i];
+ outputStream.Write(HexToUtf8Lookup, byteValue * 6, 6);
+ }
+
+ generatedArrayLength += bytesRead;
+ }
+
+ outputStream.Flush();
+ outputUtf8Writer.WriteLine("0\n};");
+ outputUtf8Writer.WriteLine($"unsigned int {symbolName}_len = {generatedArrayLength};");
+ }
+
+ private static string ToSafeSymbolName(string objectFileName)
+ {
+ // Since objectFileName includes a content hash, we can safely strip off the directory name
+ // as the filename is always unique enough. This avoid disclosing information about the build
+ // file structure in the resulting symbols.
+ var filename = Path.GetFileName(objectFileName);
+
+ // Equivalent to the logic from "xxd --include"
+ var sb = new StringBuilder();
+ foreach (var c in filename)
+ {
+ sb.Append(IsAlphanumeric(c) ? c : '_');
+ }
+
+ return sb.ToString();
+ }
+
+ // Equivalent to "isalnum"
+ private static bool IsAlphanumeric(char c) => c
+ is (>= 'a' and <= 'z')
+ or (>= 'A' and <= 'Z')
+ or (>= '0' and <= '9');
+
+ public void Cancel()
+ {
+ BuildTaskCancelled.Cancel();
+ }
+}
diff --git a/src/tasks/WasmAppBuilder/wasi/WasmResolveAssemblyDependencies.cs b/src/tasks/WasmAppBuilder/wasi/WasmResolveAssemblyDependencies.cs
new file mode 100644
index 0000000000000..f0571c8eb3abf
--- /dev/null
+++ b/src/tasks/WasmAppBuilder/wasi/WasmResolveAssemblyDependencies.cs
@@ -0,0 +1,199 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using Microsoft.Build.Framework;
+using TaskItem = Microsoft.Build.Utilities.TaskItem;
+
+namespace Microsoft.WebAssembly.Build.Tasks;
+
+///
+/// Starting from the entrypoint assembly, walks the graph of referenced assemblies using candidates from the
+/// runtime pack (first priority) or application assembly list (second priority). This is a way of reducing the
+/// number of bundled assemblies to the minimal set, instead of including every possible assembly from the runtime
+/// pack and all framework references.
+///
+public class WasmResolveAssemblyDependencies : Microsoft.Build.Utilities.Task
+{
+ [Required]
+ public string EntryPoint { get; set; } = default!;
+
+ [Required]
+ public ITaskItem[] ApplicationAssemblies { get; set; } = default!;
+
+ [Required]
+ public ITaskItem[] WasiRuntimePackAssemblies { get; set; } = default!;
+
+ [Output]
+ public ITaskItem[]? Dependencies { get; set; }
+
+ public override bool Execute()
+ {
+ var paths = ResolveRuntimeDependenciesCore(EntryPoint, ApplicationAssemblies, WasiRuntimePackAssemblies);
+ Dependencies = paths.Select(p => new TaskItem(p.Path)).ToArray();
+
+ return true;
+ }
+
+ private static List ResolveRuntimeDependenciesCore(
+ string entryPointPath,
+ IEnumerable applicationAssemblies,
+ IEnumerable runtimePackAssemblies)
+ {
+ var entryAssembly = new AssemblyEntry(entryPointPath, GetAssemblyName(entryPointPath), originalTaskItem: null);
+ var applicationAssemblyEntries = CreateAssemblyLookup(applicationAssemblies);
+ var runtimePackAssemblyEntries = CreateAssemblyLookup(runtimePackAssemblies);
+
+ var assemblyResolutionContext = new AssemblyResolutionContext(
+ entryAssembly,
+ applicationAssemblyEntries,
+ runtimePackAssemblyEntries);
+ assemblyResolutionContext.ResolveAssemblies();
+
+ return assemblyResolutionContext.Results;
+ }
+
+ private static Dictionary CreateAssemblyLookup(IEnumerable assemblies)
+ {
+ var dictionary = new Dictionary(StringComparer.Ordinal);
+ foreach (var assembly in assemblies)
+ {
+ var assemblyName = GetAssemblyName(assembly.ItemSpec);
+ if (dictionary.TryGetValue(assemblyName, out var previous))
+ {
+ throw new InvalidOperationException($"Multiple assemblies found with the same assembly name '{assemblyName}':" +
+ Environment.NewLine + string.Join(Environment.NewLine, previous, assembly.ItemSpec));
+ }
+ dictionary[assemblyName] = new AssemblyEntry(assembly.ItemSpec, assemblyName, assembly);
+ }
+
+ return dictionary;
+ }
+
+ private static string GetAssemblyName(string assemblyPath)
+ {
+ // It would be more correct to return AssemblyName.GetAssemblyName(assemblyPath).Name, but that involves
+ // actually loading the assembly file and maybe hitting a BadImageFormatException if it's not actually
+ // something that can be loaded by the active .NET version (e.g., .NET Framework if this task is running
+ // inside VS).
+ // Instead we'll rely on the filename matching the assembly name.
+ return Path.GetFileNameWithoutExtension(assemblyPath);
+ }
+
+ private sealed class AssemblyResolutionContext
+ {
+ public AssemblyResolutionContext(
+ AssemblyEntry entryAssembly,
+ Dictionary applicationAssemblies,
+ Dictionary runtimePackAssemblies)
+ {
+ EntryAssembly = entryAssembly;
+ ApplicationAssemblies = applicationAssemblies;
+ RuntimePackAssemblies = runtimePackAssemblies;
+ }
+
+ public AssemblyEntry EntryAssembly { get; }
+ public Dictionary ApplicationAssemblies { get; }
+ public Dictionary RuntimePackAssemblies { get; }
+
+ public List Results { get; } = new();
+
+ public void ResolveAssemblies()
+ {
+ var visitedAssemblies = new HashSet();
+ var pendingAssemblies = new Stack();
+ pendingAssemblies.Push(EntryAssembly.Name);
+ ResolveAssembliesCore();
+
+ void ResolveAssembliesCore()
+ {
+ while (pendingAssemblies.Count > 0)
+ {
+ var current = pendingAssemblies.Pop();
+ if (visitedAssemblies.Add(current))
+ {
+ // Not all references will be resolvable within the runtime pack.
+ // Skipping unresolved assemblies here is equivalent to passing "--skip-unresolved true" to the .NET linker.
+ if (Resolve(current) is AssemblyEntry resolved)
+ {
+ Results.Add(resolved);
+ var references = GetAssemblyReferences(resolved.Path);
+ foreach (var reference in references)
+ {
+ pendingAssemblies.Push(reference);
+ }
+ }
+ }
+ }
+ }
+
+ AssemblyEntry? Resolve(string assemblyName)
+ {
+ if (string.Equals(assemblyName, EntryAssembly.Name, StringComparison.Ordinal))
+ {
+ return EntryAssembly;
+ }
+
+ // Resolution logic. For right now, we will prefer the runtime pack version of a given
+ // assembly if there is a candidate assembly and an equivalent runtime pack assembly.
+ if (RuntimePackAssemblies.TryGetValue(assemblyName, out var assembly)
+ || ApplicationAssemblies.TryGetValue(assemblyName, out assembly))
+ {
+ return assembly;
+ }
+
+ return null;
+ }
+
+ static IReadOnlyList GetAssemblyReferences(string assemblyPath)
+ {
+ try
+ {
+ using var peReader = new PEReader(File.OpenRead(assemblyPath));
+ if (!peReader.HasMetadata)
+ {
+ return Array.Empty(); // not a managed assembly
+ }
+
+ var metadataReader = peReader.GetMetadataReader();
+
+ var references = new List();
+ foreach (var handle in metadataReader.AssemblyReferences)
+ {
+ var reference = metadataReader.GetAssemblyReference(handle);
+ var referenceName = metadataReader.GetString(reference.Name);
+
+ references.Add(referenceName);
+ }
+
+ return references;
+ }
+ catch (BadImageFormatException)
+ {
+ // not a PE file, or invalid metadata
+ }
+
+ return Array.Empty(); // not a managed assembly
+ }
+ }
+ }
+
+ internal readonly struct AssemblyEntry
+ {
+ public AssemblyEntry(string path, string name, ITaskItem? originalTaskItem)
+ {
+ Path = path;
+ Name = name;
+ _originalTaskItem = originalTaskItem;
+ }
+
+ private readonly ITaskItem? _originalTaskItem;
+ public string Path { get; }
+ public string Name { get; }
+ }
+}
diff --git a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs
index ad68f35537b92..d805f4c21a1cf 100644
--- a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs
+++ b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs
@@ -46,7 +46,8 @@ static OutOfProcessTest()
!OperatingSystem.IsIOS()
&& !OperatingSystem.IsTvOS()
&& !OperatingSystem.IsAndroid()
- && !OperatingSystem.IsBrowser();
+ && !OperatingSystem.IsBrowser()
+ && !OperatingSystem.IsOSPlatform("Wasi");
public static void RunOutOfProcessTest(string basePath, string assemblyPath)
{