Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/testing/tests.browser.targets
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<DisableBuildCompression>true</DisableBuildCompression>
<PublishTrimmed>false</PublishTrimmed>
<PublishTrimmed Condition="'$(RunAOTCompilation)' == 'true' or '$(TestTrimming)' == 'true'">true</PublishTrimmed>
<WasmTestSupport Condition="'$(RuntimeFlavor)' == 'CoreCLR'">true</WasmTestSupport>
<_WasmInTreeDefaults>false</_WasmInTreeDefaults>

<ResolveWasmOutputsDependsOn>
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/hosts/corerun/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ else()
LINK_FLAGS "--js-library ${JS_SYSTEM_NATIVE_BROWSER} --js-library ${JS_SYSTEM_BROWSER_UTILS} --extern-post-js ${JS_CORE_RUN}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
target_link_options(corerun PRIVATE
-sEXIT_RUNTIME=0
-sINITIAL_MEMORY=134217728
-sMAXIMUM_MEMORY=2147483648
-sALLOW_MEMORY_GROWTH=1
-sSTACK_SIZE=5MB
-sMODULARIZE=1
-sEXPORT_ES6=1
-sEXIT_RUNTIME=1
-sEXPORTED_RUNTIME_METHODS=ENV,${CMAKE_EMCC_EXPORTED_RUNTIME_METHODS}
-sEXPORTED_FUNCTIONS=_main,${CMAKE_EMCC_EXPORTED_FUNCTIONS}
-sEXPORT_NAME=createDotnetRuntime
Expand Down
13 changes: 12 additions & 1 deletion src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ interface DotnetHostBuilder {
* Starts the runtime and returns promise of the API object.
*/
create(): Promise<RuntimeAPI>;
/**
* @deprecated use runMain() or runMainAndExit() instead.
*/
run(): Promise<number>;
/**
* Runs the Main() method of the application and exits the runtime.
* You can provide "command line" arguments for the Main() method using
Expand All @@ -133,7 +137,14 @@ interface DotnetHostBuilder {
* Note: after the runtime exits, it would reject all further calls to the API.
* You can use runMain() if you want to keep the runtime alive.
*/
run(): Promise<number>;
runMainAndExit (): Promise<number>;
/**
* Runs the Main() method of the application and keeps the runtime alive.
* You can provide "command line" arguments for the Main() method using
* - dotnet.withApplicationArguments("A", "B", "C")
* - dotnet.withApplicationArgumentsFromQuery()
*/
runMain (): Promise<number>;
}
type MonoConfig = {
/**
Expand Down
3 changes: 2 additions & 1 deletion src/mono/browser/runtime/loader/exit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function is_runtime_running () {
}

export function assert_runtime_running () {
mono_assert(!is_exited(), () => `.NET runtime already exited with ${loaderHelpers.exitCode} ${loaderHelpers.exitReason}. You can use runtime.runMain() which doesn't exit the runtime.`);
mono_assert(!is_exited(), () => `.NET runtime already exited with ${loaderHelpers.exitCode} ${loaderHelpers.exitReason}. You can use dotnet.runMain() which doesn't exit the runtime.`);
if (WasmEnableThreads && ENVIRONMENT_IS_WORKER) {
mono_assert(runtimeHelpers.runtimeReady, "The WebWorker is not attached to the runtime. See https://github.com/dotnet/runtime/blob/main/src/mono/wasm/threads.md#JS-interop-on-dedicated-threads");
} else {
Expand Down Expand Up @@ -243,6 +243,7 @@ function abort_promises (reason: any) {
}
}

// https://github.com/dotnet/xharness/blob/799df8d4c86ff50c83b7a57df9e3691eeab813ec/src/Microsoft.DotNet.XHarness.CLI/Commands/WASM/Browser/WasmBrowserTestRunner.cs#L122-L141
function appendElementOnExit (exit_code: number) {
if (ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER && loaderHelpers.config && loaderHelpers.config.appendElementOnExit && document) {
//Tell xharness WasmBrowserTestRunner what was the exit code
Expand Down
19 changes: 18 additions & 1 deletion src/mono/browser/runtime/loader/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,11 @@ export class HostBuilder implements DotnetHostBuilder {
}
}

async run (): Promise<number> {
run (): Promise<number> {
return this.runMainAndExit();
}

async runMainAndExit (): Promise<number> {
try {
mono_assert(emscriptenModule.config, "Null moduleConfig.config");
if (!this.instance) {
Expand All @@ -261,6 +265,19 @@ export class HostBuilder implements DotnetHostBuilder {
throw err;
}
}

async runMain (): Promise<number> {
try {
mono_assert(emscriptenModule.config, "Null moduleConfig.config");
if (!this.instance) {
await this.create();
}
return this.instance!.runMain();
} catch (err) {
mono_exit(1, err);
throw err;
}
}
}

export async function createApi (): Promise<RuntimeAPI> {
Expand Down
15 changes: 14 additions & 1 deletion src/mono/browser/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ export interface DotnetHostBuilder {
*/
create(): Promise<RuntimeAPI>;

/**
* @deprecated use runMain() or runMainAndExit() instead.
*/
run(): Promise<number>;

/**
* Runs the Main() method of the application and exits the runtime.
* You can provide "command line" arguments for the Main() method using
Expand All @@ -82,7 +87,15 @@ export interface DotnetHostBuilder {
* Note: after the runtime exits, it would reject all further calls to the API.
* You can use runMain() if you want to keep the runtime alive.
*/
run(): Promise<number>;

runMainAndExit (): Promise<number>;
/**
* Runs the Main() method of the application and keeps the runtime alive.
* You can provide "command line" arguments for the Main() method using
* - dotnet.withApplicationArguments("A", "B", "C")
* - dotnet.withApplicationArgumentsFromQuery()
*/
runMain (): Promise<number>;
}

// when adding new fields, please consider if it should be impacting the config hash. If not, please drop it in the getCacheKey()
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/test-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function initRunArgs(runArgs) {
runArgs.debugging = runArgs.debugging === undefined ? false : runArgs.debugging;
runArgs.configSrc = runArgs.configSrc === undefined ? './_framework/dotnet.boot.js' : runArgs.configSrc;
// default'ing to true for tests, unless debugging
runArgs.forwardConsole = runArgs.forwardConsole === undefined ? !runArgs.debugging : runArgs.forwardConsole;
runArgs.forwardConsole = runArgs.forwardConsole === undefined ? (isFirefox && !runArgs.debugging) : runArgs.forwardConsole;
runArgs.interpreterPgo = runArgs.interpreterPgo === undefined ? false : runArgs.interpreterPgo;

return runArgs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<PropertyGroup>
<_WasmEmitSourceMapBuild>$(WasmEmitSourceMap)</_WasmEmitSourceMapBuild>
<_WasmEmitSourceMapBuild Condition="'$(_WasmEmitSourceMapBuild)' == ''">true</_WasmEmitSourceMapBuild>
<_WasmEmitDiagnosticModuleBuild Condition="'$(EnableDiagnostics)' == 'true' or '$(WasmEmitSymbolMap)' == 'true' or '$(WasmTestSupport)' == 'true'">true</_WasmEmitDiagnosticModuleBuild>
<_WasmEmitDiagnosticModuleBuild Condition="'$(_WasmEmitDiagnosticModuleBuild)' == ''">false</_WasmEmitDiagnosticModuleBuild>
</PropertyGroup>

<ComputeWasmBuildAssets
Expand All @@ -319,7 +321,7 @@ Copyright (c) .NET Foundation. All rights reserved.
CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)"
OutputPath="$(OutputPath)"
EnableThreads="$(_WasmEnableThreads)"
EnableDiagnostics="$(EnableDiagnostics)"
EnableDiagnostics="$(_WasmEmitDiagnosticModuleBuild)"
EmitSourceMap="$(_WasmEmitSourceMapBuild)"
FingerprintAssets="$(_WasmFingerprintAssets)"
FingerprintDotnetJs="$(_WasmFingerprintDotnetJs)"
Expand Down Expand Up @@ -472,7 +474,13 @@ Copyright (c) .NET Foundation. All rights reserved.
IsAot="$(RunAOTCompilation)"
IsMultiThreaded="$(WasmEnableThreads)"
FingerprintAssets="$(_WasmFingerprintAssets)"
BundlerFriendly="$(_WasmBundlerFriendlyBootConfig)" />
BundlerFriendly="$(_WasmBundlerFriendlyBootConfig)"
ExitOnUnhandledError="$(WasmTestExitOnUnhandledError)"
AppendElementOnExit="$(WasmTestAppendElementOnExit)"
LogExitCode="$(WasmTestLogExitCode)"
AsyncFlushOnExit="$(WasmTestAsyncFlushOnExit)"
ForwardConsole="$(WasmTestForwardConsole)"
/>

<ItemGroup>
<FileWrites Include="$(_WasmBuildBootJsonPath)" />
Expand Down Expand Up @@ -651,6 +659,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<PropertyGroup>
<_WasmEmitSourceMapPublish>$(WasmEmitSourceMap)</_WasmEmitSourceMapPublish>
<_WasmEmitSourceMapPublish Condition="'$(_WasmEmitSourceMapPublish)' == ''">false</_WasmEmitSourceMapPublish>
<_WasmEmitDiagnosticModulePublish Condition="'$(EnableDiagnostics)' == 'true' or '$(WasmEmitSymbolMap)' == 'true' or '$(WasmTestSupport)' == 'true'">true</_WasmEmitDiagnosticModulePublish>
<_WasmEmitDiagnosticModulePublish Condition="'$(_WasmEmitDiagnosticModulePublish)' == ''">false</_WasmEmitDiagnosticModulePublish>
</PropertyGroup>

<ItemGroup Condition="@(WasmAssembliesFinal->Count()) == 0 or '$(TargetFrameworkVersion)' == 'v6.0'">
Expand All @@ -677,7 +687,7 @@ Copyright (c) .NET Foundation. All rights reserved.
CopySymbols="$(CopyOutputSymbolsToPublishDirectory)"
ExistingAssets="@(_WasmPublishPrefilteredAssets)"
EnableThreads="$(_WasmEnableThreads)"
EnableDiagnostics="$(EnableDiagnostics)"
EnableDiagnostics="$(_WasmEmitDiagnosticModulePublish)"
EmitSourceMap="$(_WasmEmitSourceMapPublish)"
IsWebCilEnabled="$(_WasmEnableWebcil)"
FingerprintAssets="$(_WasmFingerprintAssets)"
Expand Down Expand Up @@ -885,7 +895,13 @@ Copyright (c) .NET Foundation. All rights reserved.
IsAot="$(RunAOTCompilation)"
IsMultiThreaded="$(WasmEnableThreads)"
FingerprintAssets="$(_WasmFingerprintAssets)"
BundlerFriendly="$(_WasmBundlerFriendlyBootConfig)" />
BundlerFriendly="$(_WasmBundlerFriendlyBootConfig)"
ExitOnUnhandledError="$(WasmTestExitOnUnhandledError)"
AppendElementOnExit="$(WasmTestAppendElementOnExit)"
LogExitCode="$(WasmTestLogExitCode)"
AsyncFlushOnExit="$(WasmTestAsyncFlushOnExit)"
ForwardConsole="$(WasmTestForwardConsole)"
/>

<ItemGroup>
<FileWrites Include="$(IntermediateOutputPath)$(_WasmPublishBootConfigFileName)" />
Expand Down
6 changes: 6 additions & 0 deletions src/mono/sample/wasm/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
<NestedBuildProperty Include="WasmEnableWebcil" />
<NestedBuildProperty Include="EnableAggressiveTrimming" />
<NestedBuildProperty Include="TrimMode" />
<NestedBuildProperty Include="WasmTestSupport" />
<NestedBuildProperty Include="WasmTestExitOnUnhandledError" />
<NestedBuildProperty Include="WasmTestAppendElementOnExit" />
<NestedBuildProperty Include="WasmTestLogExitCode" />
<NestedBuildProperty Include="WasmTestAsyncFlushOnExit" />
<NestedBuildProperty Include="WasmTestForwardConsole" />
</ItemGroup>

<Target Name="BuildSampleInTree"
Expand Down
10 changes: 10 additions & 0 deletions src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ public BuildEnvironment()
EnvVars["WasmFingerprintAssets"] = "false";
}

if (EnvironmentVariables.RuntimeFlavor == "CoreCLR")
{
EnvVars["WasmTestSupport"] = "true";
EnvVars["WasmTestExitOnUnhandledError"] = "true";
EnvVars["WasmTestLogExitCode"] = "true";
// EnvVars["WasmTestForwardConsole"] = "true"; // only necessary for firefox, because chromedriver supports it natively
// EnvVars["WasmTestAsyncFlushOnExit"] = "true"; // only necessary for old nodejs versions
// EnvVars["WasmTestAppendElementOnExit"] = "true"; // only used by xharness // https://github.com/dotnet/xharness/blob/799df8d4c86ff50c83b7a57df9e3691eeab813ec/src/Microsoft.DotNet.XHarness.CLI/Commands/WASM/Browser/WasmBrowserTestRunner.cs#L122-L141
}

DotNet = Path.Combine(sdkForWorkloadPath!, "dotnet");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
DotNet += ".exe";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(Configuration con
{
ProjectInfo info = CreateWasmTemplateProject(Template.WasmBrowser, config, aot: false, "browser", extraProperties: extraProperties);
UpdateBrowserProgramFile();
UpdateBrowserMainJs();
UpdateBrowserMainJs(forwardConsole: true);

string workingDir = runOutsideProjectDirectory ? BuildEnvironment.TmpPath : _projectDir;
string projectFilePath = info.ProjectFilePath;
Expand Down Expand Up @@ -169,7 +169,7 @@ public async Task BuildAndRunForDifferentOutputPaths(Configuration config, bool
{
ProjectInfo info = CreateWasmTemplateProject(Template.WasmBrowser, config, aot: false);
UpdateBrowserProgramFile();
UpdateBrowserMainJs();
UpdateBrowserMainJs(forwardConsole: true);

bool isPublish = false;
string projectDirectory = Path.GetDirectoryName(info.ProjectFilePath) ?? "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,16 @@ protected ProjectInfo CopyTestAsset(
<LatestRuntimeFrameworkVersion>11.0.0-{{versionSuffix}}</LatestRuntimeFrameworkVersion>
<RuntimePackRuntimeIdentifiers>browser-wasm;%(RuntimePackRuntimeIdentifiers)</RuntimePackRuntimeIdentifiers>
</KnownFrameworkReference>
<KnownWebAssemblySdkPack Update="Microsoft.NET.Sdk.WebAssembly.Pack">
<WebAssemblySdkPackVersion>11.0.0-{{versionSuffix}}</WebAssemblySdkPackVersion>
</KnownWebAssemblySdkPack>
""";
insertAtEnd +=
$$"""
<Target Name="_UpdateKnownWebAssemblySdkPack" BeforeTargets="ProcessFrameworkReferences">
<ItemGroup>
<KnownWebAssemblySdkPack Update="@(KnownWebAssemblySdkPack)">
<WebAssemblySdkPackVersion Condition="'%(KnownWebAssemblySdkPack.TargetFramework)' == 'net11.0'">11.0.0-{{versionSuffix}}</WebAssemblySdkPackVersion>
</KnownWebAssemblySdkPack>
</ItemGroup>
</Target>
""";
}

Expand Down Expand Up @@ -303,7 +310,7 @@ protected void DeleteFile(string pathRelativeToProjectDir)
}
}

protected void UpdateBrowserMainJs(string? targetFramework = null, string runtimeAssetsRelativePath = DefaultRuntimeAssetsRelativePath)
protected void UpdateBrowserMainJs(string? targetFramework = null, string runtimeAssetsRelativePath = DefaultRuntimeAssetsRelativePath, bool forwardConsole = false)
{
targetFramework ??= DefaultTargetFramework;
string mainJsPath = Path.Combine(_projectDir, "wwwroot", "main.js");
Expand All @@ -314,13 +321,20 @@ protected void UpdateBrowserMainJs(string? targetFramework = null, string runtim
mainJsContent,
".create()",
(targetFrameworkVersion.Major >= 8)
? ".withConfig({ forwardConsole: true, appendElementOnExit: true, logExitCode: true, exitOnUnhandledError: true }).create()"
: ".withConfig({ forwardConsole: true, appendElementOnExit: true, logExitCode: true }).create()"
? $".withConfig({{ forwardConsole: {forwardConsole.ToString().ToLowerInvariant()}, appendElementOnExit: true, logExitCode: true, exitOnUnhandledError: true }}).create()"
: ".withConfig({ appendElementOnExit: true, logExitCode: true }).create()"
);

// dotnet.run() is used instead of runMain() in net9.0+
if (targetFrameworkVersion.Major >= 9)
if (targetFrameworkVersion.Major >= 11)
{
// runMainAndExit() is used instead of runMain() in net11.0+
updatedMainJsContent = StringReplaceWithAssert(updatedMainJsContent, "runMain()", "runMainAndExit()");
}
else if (targetFrameworkVersion.Major >= 9)
{
// dotnet.run() is used instead of runMain() in net9.0+
updatedMainJsContent = StringReplaceWithAssert(updatedMainJsContent, "runMain()", "dotnet.run()");
}

updatedMainJsContent = StringReplaceWithAssert(updatedMainJsContent, "from './_framework/dotnet.js'", $"from '{runtimeAssetsRelativePath}dotnet.js'");

Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/Wasm.Build.Tests/WasmBrowserRunMainOnly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public async Task RunMainOnly()
Configuration config = Configuration.Debug;

ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBrowserRunMainOnly, $"WasmBrowserRunMainOnly");
var (_, buildOutput) = PublishProject(info, config);
var (_, buildOutput) = PublishProject(info, config, new PublishOptions(AssertAppBundle: false, EnableDiagnostics: true));

// ** MicrosoftNetCoreAppRuntimePackDir : '....microsoft.netcore.app.runtime.browser-wasm\11.0.0-dev'
Assert.Contains("microsoft.netcore.app.runtime.browser-wasm", buildOutput);
Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/host/BrowserHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke
var runArgsJson = new RunArgumentsJson(applicationArguments: _args.AppArgs,
runtimeArguments: _args.CommonConfig.RuntimeArguments,
environmentVariables: envVars,
forwardConsoleToWS: _args.ForwardConsoleOutput ?? false,
forwardConsole: _args.ForwardConsoleOutput ?? false,
debugging: _args.CommonConfig.Debugging);
runArgsJson.Save(Path.Combine(_args.CommonConfig.AppPath, "runArgs.json"));

Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/host/RunArgumentsJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal sealed record RunArgumentsJson(
string[] applicationArguments,
string[]? runtimeArguments = null,
IDictionary<string, string>? environmentVariables = null,
bool forwardConsoleToWS = false,
bool forwardConsole = false,
bool debugging = false
)
{
Expand Down
4 changes: 2 additions & 2 deletions src/mono/wasm/templates/templates/browser/wwwroot/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { dotnet } from './_framework/dotnet.js'

const { setModuleImports, getAssemblyExports, getConfig, runMain } = await dotnet
const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
.withApplicationArguments("start")
.create();

Expand All @@ -29,4 +29,4 @@ pauseButton.addEventListener('click', e => {
});

// run the C# Main() method and keep the runtime process running and executing further API calls
await runMain();
await dotnet.runMain();
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ public static void Run()
// In the test case it is done in the JS before call to this method
var text = JsonSerializer.Serialize(new Person("John", "Doe"), PersonJsonSerializerContext.Default.Person);
TestOutput.WriteLine(text);
Console.WriteLine("LazyLoadingTest done");
Console.Out.Flush();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,7 @@ try {
break;
}
} catch (e) {
exit(1, e);
if (e.name != "ExitStatus") {
exit(1, e);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public partial class Foo
public static int Bar()
{
Console.WriteLine("Hello from Foo.Bar!");
Console.Out.Flush();
return 42;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,4 @@

import { dotnet } from './_framework/dotnet.js'

await dotnet.create();

try {
await dotnet.run();
console.log("WASM EXIT 0");
} catch (err) {
console.error(err);
console.log("WASM EXIT 1");
}
await dotnet.runMainAndExit();
Loading
Loading