artifactName: BrowserWasm
displayName: BrowserWasm
- - script: "mkdir $(librariesDownloadDir)/bin/wasm;unzip -o $(librariesDownloadDir)/BrowserWasm/artifacts/packages/Release/Shipping/Microsoft.NETCore.App.Runtime.Mono.browser-wasm.7.0.0-ci.nupkg data/* runtimes/* -d $(librariesDownloadDir)/bin/wasm;cp src/mono/wasm/runtime-test.js $(librariesDownloadDir)/bin/wasm/runtime-test.js;find $(librariesDownloadDir)/bin/wasm -type f -exec chmod 664 {} \\;"
+ - script: "mkdir $(librariesDownloadDir)/bin/wasm;unzip -o $(librariesDownloadDir)/BrowserWasm/artifacts/packages/Release/Shipping/Microsoft.NETCore.App.Runtime.Mono.browser-wasm.7.0.0-ci.nupkg data/* runtimes/* -d $(librariesDownloadDir)/bin/wasm;cp src/mono/wasm/test-main.js $(librariesDownloadDir)/bin/wasm/test-main.js;find $(librariesDownloadDir)/bin/wasm -type f -exec chmod 664 {} \\;"
displayName: "Create wasm directory (Linux)"
# Download mono AOT
<_XHarnessArgs Condition="'$(OS)' != 'Windows_NT'">wasm $XHARNESS_COMMAND --app=. --output-directory=$XHARNESS_OUT</_XHarnessArgs>
<_XHarnessArgs Condition="'$(OS)' == 'Windows_NT'">wasm %XHARNESS_COMMAND% --app=. --output-directory=%XHARNESS_OUT%</_XHarnessArgs>
- <_XHarnessArgs Condition="'$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps'">$(_XHarnessArgs) --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js</_XHarnessArgs>
+ <_XHarnessArgs Condition="'$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps'">$(_XHarnessArgs) --engine=$(JSEngine) $(JSEngineArgs) --js-file=main.js</_XHarnessArgs>
<_XHarnessArgs Condition="'$(BrowserHost)' == 'windows'">$(_XHarnessArgs) --browser=chrome --browser-path=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe</_XHarnessArgs>
<_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)</_XHarnessArgs>
<_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)</_XHarnessArgs>
<_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(Scenario)' != 'BuildWasmApps'">--run WasmTestRunner.dll $(AssemblyName).dll</_AppArgs>
- <_AppArgs Condition="'$(IsFunctionalTest)' == 'true'">--run $(AssemblyName).dll --testing</_AppArgs>
+ <_AppArgs Condition="'$(IsFunctionalTest)' == 'true'">--run $(AssemblyName).dll</_AppArgs>
<_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs)</_AppArgs>
<PropertyGroup>
<WasmAppDir>$(BundleDir)</WasmAppDir>
<WasmMainAssemblyFileName Condition="'$(WasmMainAssemblyFileName)' == ''">WasmTestRunner.dll</WasmMainAssemblyFileName>
- <WasmMainJSPath Condition="'$(WasmMainJSPath)' == ''">$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath Condition="'$(WasmMainJSPath)' == ''">$(MonoProjectRoot)\wasm\test-main.js</WasmMainJSPath>
<WasmInvariantGlobalization>$(InvariantGlobalization)</WasmInvariantGlobalization>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
<WasmNativeStrip>false</WasmNativeStrip>
<HelixWorkItem Include="@(_RunOnlyWorkItem -> '%(FileName)')" >
<PayloadArchive>%(Identity)</PayloadArchive>
<!-- No RunTests script generated for the sample project so we just use the direct command -->
- <Command>$(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=runtime.js --output-directory=$(XHarnessOutput) -- --run %(FileName).dll</Command>
+ <Command>$(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=main.js --output-directory=$(XHarnessOutput) -- --run %(FileName).dll</Command>
</HelixWorkItem>
</ItemGroup>
<HelixWorkItem Include="@(_RunOnlyWorkItem -> '%(FileName)')" >
<PayloadArchive>%(Identity)</PayloadArchive>
<!-- No RunTests script generated for the sample project so we just use the direct command -->
- <Command>$(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- %(FileName).dll --testing</Command>
+ <Command>$(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- %(FileName).dll</Command>
</HelixWorkItem>
</ItemGroup>
<OutputPath>bin</OutputPath>
<WasmAppDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\AppBundle\</WasmAppDir>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
<EnableDefaultItems>false</EnableDefaultItems>
<!-- Important - deltas don't support trimming! -->
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
- <head>
- <title>TESTS</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body>
- <h3 id="header">Wasm Browser Sample</h3>
- Result from Sample.Test.TestMeaning: <span id="out"></span>
- <div>
- Click here (upto 2 times): <button id="update">Update</button>
- </div>
- <script type='text/javascript'>
- var App = {
- init: function () {
- var outElement = document.getElementById("out");
- document.getElementById("update").addEventListener("click", function () {
- INTERNAL.call_static_method("[WasmDelta] Sample.Test:Update", []);
- console.log ("applied update");
- var ret = INTERNAL.call_static_method("[WasmDelta] Sample.Test:TestMeaning", []);
- outElement.innerHTML = ret;
- })
- var ret = INTERNAL.call_static_method("[WasmDelta] Sample.Test:TestMeaning", []);
- outElement.innerHTML = ret;
- console.log ("ready");
- },
- };
- </script>
- <script type="text/javascript" src="runtime.js"></script>
- <script defer src="dotnet.js"></script>
+<head>
+ <title>Hot Reload Sample</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+<body>
+ <h3 id="header">Wasm Hot Reload Sample</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <div>
+ Click here (upto 2 times): <button id="update">Update</button>
+ </div>
+ <script type='text/javascript'>
+ const App = {
+ init: function () {
+ const update = BINDING.bind_static_method("[WasmDelta] Sample.Test:Update");
+ const testMeaning = BINDING.bind_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning");
+ const outElement = document.getElementById("out");
+ document.getElementById("update").addEventListener("click", function () {
+ update();
+ console.log("applied update");
+ outElement.innerHTML = testMeaning();
+ })
+ outElement.innerHTML = testMeaning();
+ console.log("ready");
+ },
+ };
+ </script>
+ <script type="text/javascript" src="main.js"></script>
+ <script defer src="dotnet.js"></script>
+</body>
- </body>
-</html>
+</html>
\ No newline at end of file
"use strict";
var Module = {
- config: null,
configSrc: "./mono-config.json",
onConfigLoaded: function () {
MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
<Exec Command="$(_Dotnet) publish /p:Configuration=$(Configuration) /p:TargetArchitecture=wasm /p:TargetOS=Browser $(_AOTFlag) $(_SampleProject)" />
</Target>
<Target Name="RunSampleWithV8" DependsOnTargets="BuildSampleInTree">
- <Exec WorkingDirectory="bin/$(Configuration)/AppBundle" Command="v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run $(_SampleAssembly) $(Args)" IgnoreExitCode="true" />
+ <Exec WorkingDirectory="bin/$(Configuration)/AppBundle" Command="v8 --expose_wasm main.js -- $(DOTNET_MONO_LOG_LEVEL) --run $(_SampleAssembly) $(Args)" IgnoreExitCode="true" />
</Target>
<Target Name="CheckServe">
<Exec Command="dotnet tool install -g dotnet-serve" IgnoreExitCode="true" />
</Target>
<Target Name="RunSampleWithBrowser" DependsOnTargets="BuildSampleInTree;CheckServe">
- <Exec Command="$(_Dotnet) serve -o -d:bin/$(Configuration)/AppBundle -p:8000" IgnoreExitCode="true" YieldDuringToolExecution="true" />
+ <Exec Command="$(_Dotnet) serve -o -d:bin/$(Configuration)/AppBundle -p:8000 --mime .mjs=text/javascript" IgnoreExitCode="true" YieldDuringToolExecution="true" />
</Target>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
- <WasmMainJSPath>$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>$(MonoProjectRoot)\wasm\test-main.js</WasmMainJSPath>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
</PropertyGroup>
<PropertyGroup>
<!-- don't need to run this on helix -->
<WasmCopyAppZipToHelixTestDir>false</WasmCopyAppZipToHelixTestDir>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
</PropertyGroup>
<h3 id="header">Wasm Browser Sample - App task frame</h3>
<span id="out"></span>
<script type='text/javascript'>
- var test_exit = function(exit_code)
+ function set_exit_code (exit_code, reason)
{
/* Set result in a tests_done element, to be read by xharness */
var tests_done_elem = document.createElement("label");
};
</script>
- <script type="text/javascript" src="runtime.js"></script>
+ <script type="text/javascript" src="main.js"></script>
<script defer src="dotnet.js"></script>
</body>
</html>
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
- <head>
- <title>TESTS</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <link rel="stylesheet" href="style.css">
- </head>
- <body onload="onLoad()">
- <h3 id="header">Wasm Browser Sample - Simple Benchmark</h3>
- Output:<br><br> <span id="out"></span>
- <script type='text/javascript'>
- var is_testing = false;
- var tasks = '';
- var onLoad = function() {
- var url = new URL(decodeURI(window.location));
- let args = url.searchParams.getAll('arg');
- is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
- tasks = url.searchParams.getAll('task');
- };
- var test_exit = function(exit_code)
- {
- if (!is_testing) {
- console.log(`test_exit: ${exit_code}`);
- return;
- }
+<head>
+ <title>Benchmark Sample</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="style.css">
+</head>
- /* Set result in a tests_done element, to be read by xharness */
- var tests_done_elem = document.createElement("label");
- tests_done_elem.id = "tests_done";
- tests_done_elem.innerHTML = exit_code.toString();
- document.body.appendChild(tests_done_elem);
+<body onload="onLoad()">
+ <h3 id="header">Wasm Browser Sample - Simple Benchmark</h3>
+ Output:<br><br> <span id="out"></span>
+ <script type='text/javascript'>
+ let tasks = '';
+ var onLoad = function () {
+ var url = new URL(decodeURI(window.location));
+ tasks = url.searchParams.getAll('task');
+ };
- console.log(`WASM EXIT ${exit_code}`);
- };
+ function set_exit_code(exit_code, reason) {
+ /* Set result in a tests_done element, to be read by xharness */
+ const tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
- function yieldBench () {
- let promise = INTERNAL.call_static_method("[Wasm.Browser.Bench.Sample] Sample.Test:RunBenchmark", []);
- promise.then(ret => {
- document.getElementById("out").innerHTML += ret;
- if (ret.length > 0) {
- setTimeout(function () { yieldBench(); }, 0);
- } else {
- document.getElementById("out").innerHTML += "Finished";
- }
- });
- }
+ console.log(`WASM EXIT ${exit_code}`);
+ };
- var App = {
- init: function () {
- if (tasks != '')
- INTERNAL.call_static_method("[Wasm.Browser.Bench.Sample] Sample.Test:SetTasks", tasks);
- yieldBench ();
- },
+ function yieldBench() {
+ const runBenchmark = BINDING.bind_static_method("[Wasm.Browser.Bench.Sample] Sample.Test:RunBenchmark");
+ let promise = runBenchmark();
+ promise.then(ret => {
+ document.getElementById("out").innerHTML += ret;
+ if (ret.length > 0) {
+ setTimeout(function () { yieldBench(); }, 0);
+ } else {
+ document.getElementById("out").innerHTML += "Finished";
+ }
+ });
+ }
- PageShow: async function ()
- {
- AppStart.Construct();
- try {
- await AppStart.WaitForPageShow();
- } finally {
- AppStart.RemoveFrame();
- }
- },
+ const App = {
+ init: function () {
+ if (tasks != '') {
+ const setTasks = BINDING.bind_static_method("[Wasm.Browser.Bench.Sample] Sample.Test:SetTasks");
+ setTasks(tasks);
+ }
+ yieldBench();
+ },
- ReachedManaged: async function ()
- {
- AppStart.Construct();
- try {
- await AppStart.WaitForReached();
- } finally {
- AppStart.RemoveFrame();
- }
+ PageShow: async function () {
+ AppStart.Construct();
+ try {
+ await AppStart.WaitForPageShow();
+ } finally {
+ AppStart.RemoveFrame();
}
- };
- </script>
- <script type="text/javascript" src="runtime.js"></script>
- <script type="text/javascript" src="appstart.js"></script>
+ },
- <script defer src="dotnet.js"></script>
+ ReachedManaged: async function () {
+ AppStart.Construct();
+ try {
+ await AppStart.WaitForReached();
+ } finally {
+ AppStart.RemoveFrame();
+ }
+ }
+ };
+ </script>
+ <script type="text/javascript" src="main.js"></script>
+ <script type="text/javascript" src="appstart.js"></script>
+ <script defer src="dotnet.js"></script>
+</body>
- </body>
-</html>
+</html>
\ No newline at end of file
"use strict";
var Module = {
- config: null,
configSrc: "./mono-config.json",
- onDotNetReady: function () {
+ onDotNetReady: () => {
try {
App.init();
} catch (error) {
console.log("exception: " + error);
- test_exit(1);
+ set_exit_code(1, error);
throw (error);
}
},
- onAbort: function (err) {
- test_exit(1);
+ onAbort: (error) => {
+ set_exit_code(1, error);
},
};
public static void StopProfile(){}
```
-2. Initialize the profiler in the main javascript (e.g. runtime.js)
+2. Initialize the profiler in the main javascript (e.g. main.js)
```
var Module = {
- onRuntimeInitialized: function () {
+ onConfigLoaded: () => {
...
if (config.enable_profiler)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
<WasmProfilers>aot;</WasmProfilers>
</PropertyGroup>
<WasmExtraConfig Include="enable_profiler" Value="true" Condition="'$(EnableProfiler)' == 'true'" />
<WasmExtraFilesToDeploy Include="index.html" />
</ItemGroup>
+
+ <Target Name="RunSample" DependsOnTargets="RunSampleWithBrowser" />
</Project>
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
<head>
- <title>TESTS</title>
+ <title>Profiler Sample</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
- <h3 id="header">Wasm Browser Sample</h3>
+ <h3 id="header">Wasm Profiler Sample</h3>
Result from Sample.Test.TestMeaning: <span id="out"></span>
- <script type="text/javascript" src="runtime.js"></script>
+ <script type="text/javascript" src="main.js"></script>
<script defer src="dotnet.js"></script>
</body>
"use strict";
var Module = {
- is_testing: false,
- config: null,
configSrc: "./mono-config.json",
- onConfigLoaded: function () {
+ onConfigLoaded: () => {
if (MONO.config.enable_profiler) {
MONO.config.aot_profiler_options = {
write_at: "Sample.Test::StopProfile",
}
}
},
- onDotNetReady: function () {
+ onDotNetReady: () => {
try {
Module.init();
} catch (error) {
- test_exit(1);
+ set_exit_code(1, error);
throw (error);
}
},
- onAbort: function (err) {
- test_exit(1);
+ onAbort: (error) => {
+ set_exit_code(1, error);
},
- init: function () {
+ init: () => {
console.log("not ready yet")
- const ret = INTERNAL.call_static_method("[Wasm.BrowserProfile.Sample] Sample.Test:TestMeaning", []);
+ const testMeaning = BINDING.bind_static_method("[Wasm.BrowserProfile.Sample] Sample.Test:TestMeaning");
+ const stopProfile = BINDING.bind_static_method("[Wasm.BrowserProfile.Sample] Sample.Test:StopProfile");
+ const ret = testMeaning();
document.getElementById("out").innerHTML = ret;
console.log("ready");
- if (Module.is_testing) {
- console.debug(`ret: ${ret}`);
- let exit_code = ret == 42 ? 0 : 1;
- Module.test_exit(exit_code);
- }
+ console.debug(`ret: ${ret}`);
+ let exit_code = ret == 42 ? 0 : 1;
+ Module.set_exit_code(exit_code);
if (MONO.config.enable_profiler) {
- INTERNAL.call_static_method("[Wasm.BrowserProfile.Sample] Sample.Test:StopProfile", []);
+ stopProfile();
Module.saveProfile();
}
},
- test_exit: function (exit_code) {
- if (!Module.is_testing) {
- console.log(`test_exit: ${exit_code}`);
- return;
- }
-
+ set_exit_code: (exit_code, reason) => {
/* Set result in a tests_done element, to be read by xharness */
const tests_done_elem = document.createElement("label");
tests_done_elem.id = "tests_done";
console.log(`WASM EXIT ${exit_code}`);
},
- saveProfile: function () {
+ saveProfile: () => {
const a = document.createElement('a');
const blob = new Blob([INTERNAL.aot_profile_data]);
a.href = URL.createObjectURL(blob);
<PropertyGroup>
<Configuration>Debug</Configuration>
<WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
<WasmDebugLevel>1</WasmDebugLevel>
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
- <head>
- <title>TESTS</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body onload="onLoad()">
- <h3 id="header">Wasm Browser Sample</h3>
- Result from Sample.Test.TestMeaning: <span id="out"></span>
- <script type='text/javascript'>
- var is_testing = false;
- var onLoad = function() {
- var url = new URL(decodeURI(window.location));
- let args = url.searchParams.getAll('arg');
- is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
- };
- var test_exit = function(exit_code)
- {
- if (!is_testing) {
- console.log(`test_exit: ${exit_code}`);
- return;
- }
+<head>
+ <title>Sample</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
- /* Set result in a tests_done element, to be read by xharness */
- var tests_done_elem = document.createElement("label");
- tests_done_elem.id = "tests_done";
- tests_done_elem.innerHTML = exit_code.toString();
- document.body.appendChild(tests_done_elem);
+<body>
+ <h3 id="header">Wasm Browser Sample</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <script type='text/javascript'>
+ function set_exit_code(exit_code, reason) {
+ /* Set result in a tests_done element, to be read by xharness */
+ const tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
- console.log(`WASM EXIT ${exit_code}`);
- };
+ console.log(`WASM EXIT ${exit_code}`);
+ };
- var App = {
- init: function () {
- var ret = INTERNAL.call_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning", []);
- document.getElementById("out").innerHTML = ret;
+ const App = {
+ init: () => {
+ const testMeaning = BINDING.bind_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning");
+ const ret = testMeaning();
+ document.getElementById("out").innerHTML = ret;
- if (is_testing)
- {
- console.debug(`ret: ${ret}`);
- let exit_code = ret == 42 ? 0 : 1;
- test_exit(exit_code);
- }
- },
- };
- </script>
- <script type="text/javascript" src="runtime.js"></script>
+ console.debug(`ret: ${ret}`);
+ let exit_code = ret == 42 ? 0 : 1;
+ set_exit_code(exit_code);
+ },
+ };
+ </script>
+ <script type="text/javascript" src="main.js"></script>
+ <script defer src="dotnet.js"></script>
- <script defer src="dotnet.js"></script>
+</body>
- </body>
</html>
\ No newline at end of file
// The .NET Foundation licenses this file to you under the MIT license.
"use strict";
+
var Module = {
- config: null,
configSrc: "./mono-config.json",
- onDotNetReady: function () {
+ onDotNetReady: () => {
try {
App.init();
} catch (error) {
- test_exit(1);
+ set_exit_code(1, error);
throw (error);
}
},
- onAbort: function () {
- test_exit(1);
-
+ onAbort: (error) => {
+ set_exit_code(1, error);
},
-};
+};
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
- <WasmMainJSPath>$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>$(MonoProjectRoot)\wasm\test-main.js</WasmMainJSPath>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
</PropertyGroup>
fi
run-console:
- cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --stack-trace-limit=1000 --single-threaded --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run $(CONSOLE_DLL) $(ARGS)
+ cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --stack-trace-limit=1000 --single-threaded --expose_wasm main.js -- $(DOTNET_MONO_LOG_LEVEL) --run $(CONSOLE_DLL) $(ARGS)
A dotnet wasm app has some native wasm files (`dotnet.wasm`, and `dotnet.js`). How these files are obtained, or generated:
1. Build
- a. with no native libraries referenced (AOT setting is ignored here)
+ - a. with no native libraries referenced (AOT setting is ignored here)
- files from the runtime pack are used as-is
- b. with native libraries referenced
+ - b. with native libraries referenced
- dotnet.wasm is relinked with the native libraries
2. Publish
- dotnet.wasm is relinked with the native libraries, and updated pinvoke/icalls from the trimmed assemblies
<_WasmRuntimePackSrcFile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" />
<_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" Exclude="$(_WasmRuntimePackSrcDir)\*.iffe.js"/>
- <_WasmExtraJSFile Include="$(_WasmRuntimePackSrcDir)\*.iffe.js" Kind="pre-js" />
+ <_WasmExtraJSFile Include="$(_WasmRuntimePackSrcDir)\*.iffe.js" Kind="extern-pre-js" />
<_WasmNativeFileForLinking Include="@(NativeFileReference)" />
</ItemGroup>
<_EmccLinkStepArgs Include="--js-library "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' == 'js-library'" />
<_EmccLinkStepArgs Include="--pre-js "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' == 'pre-js'" />
+ <_EmccLinkStepArgs Include="--extern-pre-js "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' == 'extern-pre-js'" />
<_EmccLinkStepArgs Include="--post-js "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' == 'post-js'" />
- <_WasmLinkDependencies Include="@(_WasmExtraJSFile)" Condition="'%(_WasmExtraJSFile.Kind)' == 'js-library' or '%(_WasmExtraJSFile.Kind)' == 'pre-js' or '%(_WasmExtraJSFile.Kind)' == 'post-js'" />
+ <_WasmLinkDependencies Include="@(_WasmExtraJSFile)" Condition="'%(_WasmExtraJSFile.Kind)' == 'js-library' or '%(_WasmExtraJSFile.Kind)' == 'pre-js' or '%(_WasmExtraJSFile.Kind)' == 'post-js' or '%(_WasmExtraJSFile.Kind)' == 'extern-post-js'" />
<_EmccLinkStepArgs Include=""%(_WasmNativeFileForLinking.Identity)"" />
<_WasmLinkDependencies Include="@(_WasmNativeFileForLinking)" />
<Error Condition="'$(WasmMainAssemblyFileName)' == ''" Text="%24(WasmMainAssemblyFileName) property needs to be set for generating $(WasmRunV8ScriptPath)." />
<WriteLinesToFile
File="$(WasmRunV8ScriptPath)"
- Lines="v8 --expose_wasm runtime.js -- ${RUNTIME_ARGS} --run $(WasmMainAssemblyFileName) $*"
+ Lines="v8 --expose_wasm main.js -- ${RUNTIME_ARGS} --run $(WasmMainAssemblyFileName) $*"
Overwrite="true">
</WriteLinesToFile>
<PropertyGroup>
<WasmAppDir>$(TestRootDir)AppBundle\</WasmAppDir>
<WasmMainAssemblyFileName>$(OriginalPublishDir)WasmTestRunner.dll</WasmMainAssemblyFileName>
- <WasmMainJSPath>$(OriginalPublishDir)runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>$(OriginalPublishDir)test-main.js</WasmMainJSPath>
<WasmGenerateRunV8Script Condition="'$(WasmGenerateRunV8Script)' == ''">true</WasmGenerateRunV8Script>
</PropertyGroup>
Assert.NotNull(loc["scriptId"]);
Assert.Equal("dotnet://debugger-test.dll/debugger-test.cs", scripts[loc["scriptId"]?.Value<string>()]);
- Assert.Equal(10, loc["lineNumber"]);
- Assert.Equal(8, loc["columnNumber"]);
+ Assert.Equal(10, (int)loc["lineNumber"]);
+ Assert.Equal(8, (int)loc["columnNumber"]);
}
[Fact]
var loc = bp1_res.Value["locations"]?.Value<JArray>()[0];
Assert.NotNull(loc["scriptId"]);
- Assert.Equal(13, loc["lineNumber"]);
- Assert.Equal(24, loc["columnNumber"]);
+ Assert.Equal(13, (int)loc["lineNumber"]);
+ Assert.Equal(24, (int)loc["columnNumber"]);
var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 33);
var loc2 = bp2_res.Value["locations"]?.Value<JArray>()[0];
Assert.NotNull(loc2["scriptId"]);
- Assert.Equal(13, loc2["lineNumber"]);
- Assert.Equal(33, loc2["columnNumber"]);
+ Assert.Equal(13, (int)loc2["lineNumber"]);
+ Assert.Equal(33, (int)loc2["columnNumber"]);
}
[Fact]
var loc = bp1_res.Value["locations"]?.Value<JArray>()[0];
Assert.NotNull(loc["scriptId"]);
- Assert.Equal(13, loc["lineNumber"]);
- Assert.Equal(24, loc["columnNumber"]);
+ Assert.Equal(13, (int)loc["lineNumber"]);
+ Assert.Equal(24, (int)loc["columnNumber"]);
var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 33);
var loc2 = bp2_res.Value["locations"]?.Value<JArray>()[0];
Assert.NotNull(loc2["scriptId"]);
- Assert.Equal(13, loc2["lineNumber"]);
- Assert.Equal(33, loc2["columnNumber"]);
+ Assert.Equal(13, (int)loc2["lineNumber"]);
+ Assert.Equal(33, (int)loc2["columnNumber"]);
}
[Theory]
window.location.replace("http://localhost:9400/non-wasm-page.html");
}
</script>
- <script type="text/javascript" src="runtime-debugger.js"></script>
+ <script type="text/javascript" src="debugger-main.js"></script>
<script type="text/javascript" src="other.js"></script>
<script async type="text/javascript" src="dotnet.js"></script>
Stuff goes here
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+"use strict";
+
+var Module = {
+ configSrc: "./mono-config.json",
+ onConfigLoaded: () => {
+ MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
+ // For custom logging patch the functions below
+ /*
+ MONO.config.environment_variables["MONO_LOG_LEVEL"] = "debug";
+ MONO.config.environment_variables["MONO_LOG_MASK"] = "all";
+ INTERNAL.logging = {
+ trace: function (domain, log_level, message, isFatal, dataPtr) { },
+ debugger: function (level, message) { }
+ };
+ */
+ },
+ onDotNetReady: () => {
+ App.init();
+ },
+};
<WasmExtraFilesToDeploy Include="debugger-driver.html" />
<WasmExtraFilesToDeploy Include="non-wasm-page.html" />
<WasmExtraFilesToDeploy Include="other.js" />
- <WasmExtraFilesToDeploy Include="runtime-debugger.js" />
+ <WasmExtraFilesToDeploy Include="debugger-main.js" />
<WasmExtraFilesToDeploy Include="weather.json" />
<!-- We want to bundle these assemblies, so build them first -->
<PropertyGroup>
<EnableDefaultWasmAssembliesToBundle>false</EnableDefaultWasmAssembliesToBundle>
<WasmAppDir>$(AppDir)</WasmAppDir>
- <WasmMainJSPath>$(MonoProjectRoot)wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>$(MonoProjectRoot)wasm\test-main.js</WasmMainJSPath>
<!-- like is used on blazor -->
<WasmDebugLevel Condition="'$(WasmDebugLevel)'==''">-1</WasmDebugLevel>
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-"use strict";
-
-var Module = {
- config: null,
- configSrc: "./mono-config.json",
- onConfigLoaded: function () {
- MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
- // For custom logging patch the functions below
- /*
- MONO.config.environment_variables["MONO_LOG_LEVEL"] = "debug";
- MONO.config.environment_variables["MONO_LOG_MASK"] = "all";
- INTERNAL.logging = {
- trace: function (domain, log_level, message, isFatal, dataPtr) { },
- debugger: function (level, message) { }
- };
- */
- },
- onDotNetReady: function () {
- App.init();
- },
-};
set_target_properties(dotnet PROPERTIES
LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/runtime.iffe.js;${SOURCE_DIR}/library-dotnet.js;${SYSTEM_NATIVE_DIR}/pal_random.js"
- LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --pre-js ${NATIVE_BIN_DIR}/src/runtime.iffe.js --js-library ${SOURCE_DIR}/library-dotnet.js --js-library ${SYSTEM_NATIVE_DIR}/pal_random.js"
+ LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --extern-pre-js ${NATIVE_BIN_DIR}/src/runtime.iffe.js --js-library ${SOURCE_DIR}/library-dotnet.js --js-library ${SYSTEM_NATIVE_DIR}/pal_random.js"
RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}")
if(CMAKE_BUILD_TYPE STREQUAL "Release")
// The .NET Foundation licenses this file to you under the MIT license.
import { Int32Ptr, JSHandle, MonoArray, MonoObject, MonoString, VoidPtr } from "./types";
-import { Module } from "./modules";
+import { Module } from "./imports";
import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles";
import { wrap_error } from "./method-calls";
import { _js_to_mono_obj } from "./js-to-cs";
import { JSHandle, GCHandle, MonoObject } from "./types";
import { ArgsMarshalString } from "./method-binding";
import { PromiseControl } from "./cancelable-promise";
-import { runtimeHelpers } from "./modules";
+import { runtimeHelpers } from "./imports";
const fn_signatures: [jsname: string, csname: string, signature: ArgsMarshalString][] = [
["_get_cs_owned_object_by_js_handle", "GetCSOwnedObjectByJSHandle", "ii!"],
MonoArrayNull, MonoObject, MonoObjectNull, MonoString,
MonoType, MonoTypeNull
} from "./types";
-import { runtimeHelpers } from "./modules";
+import { runtimeHelpers } from "./imports";
import { conv_string } from "./strings";
import corebindings from "./corebindings";
import cwraps from "./cwraps";
MonoMethod, MonoObject, MonoString,
MonoType, VoidPtr
} from "./types";
-import { Module } from "./modules";
+import { Module } from "./imports";
const fn_signatures: [ident: string, returnType: string | null, argTypes?: string[], opts?: any][] = [
// MONO
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import { Module, MONO, runtimeHelpers } from "./modules";
+import { Module, MONO, runtimeHelpers } from "./imports";
import { toBase64StringImpl } from "./base64";
import cwraps from "./cwraps";
import { VoidPtr } from "./types";
--- /dev/null
+import { DotNetPublicAPI } from "./exports";
+import { EmscriptenModuleConfig } from "./types";
+
+// this is the only public export from the dotnet.js module
+declare function createDotnetRuntime(moduleFactory: (api: DotNetPublicAPI) => EmscriptenModuleConfig): Promise<DotNetPublicAPI>;
+export default createDotnetRuntime;
+
mono_wasm_raise_debug_event,
mono_wasm_fire_debugger_agent_message,
} from "./debug";
-import { runtimeHelpers, setLegacyModules } from "./modules";
+import { runtimeHelpers, setImportsAndExports } from "./imports";
import { EmscriptenModuleMono, MonoArray, MonoConfig, MonoConfigError, MonoObject } from "./types";
import {
mono_load_runtime_and_bcl_args, mono_wasm_load_config,
getU8, getU16, getU32, getF32, getF64,
} from "./memory";
-export const MONO: MONO = <any>{
+const MONO: MONO = <any>{
// current "public" MONO API
mono_wasm_setenv,
mono_wasm_load_bytes_into_heap,
mono_wasm_new_roots,
};
-export const BINDING: BINDING = <any>{
+const BINDING: BINDING = <any>{
//current "public" BINDING API
mono_obj_array_new: cwraps.mono_wasm_obj_array_new,
mono_obj_array_set: cwraps.mono_wasm_obj_array_set,
// this is executed early during load of emscripten runtime
// it exports methods to global objects MONO, BINDING and Module in backward compatible way
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-function export_to_emscripten(dotnet: any, mono: any, binding: any, internal: any, module: any): void {
- const moduleExt = module as EmscriptenModuleMono;
+function initializeImportsAndExports(
+ imports: { isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function },
+ exports: { mono: any, binding: any, internal: any, module: any },
+): void {
+ const module = exports.module as EmscriptenModuleMono;
+ const globalThisAny = globalThis as any;
// we want to have same instance of MONO, BINDING and Module in dotnet iffe
- setLegacyModules(dotnet, mono, binding, internal, module);
+ setImportsAndExports(imports, exports);
- // here we merge methods to it from the local objects
- Object.assign(dotnet, DOTNET);
- Object.assign(mono, MONO);
- Object.assign(binding, BINDING);
- Object.assign(internal, INTERNAL);
+ // here we merge methods from the local objects into exported objects
+ Object.assign(exports.mono, MONO);
+ Object.assign(exports.binding, BINDING);
+ Object.assign(exports.internal, INTERNAL);
+ const api: DotNetPublicAPI = <any>{
+ MONO: exports.mono,
+ BINDING: exports.binding,
+ INTERNAL: exports.internal,
+ Module: module
+ };
+
+ if (module.configSrc) {
+ // this could be overriden on Module
+ if (!module.preInit) {
+ module.preInit = [];
+ } else if (typeof module.preInit === "function") {
+ module.preInit = [module.preInit];
+ }
+ module.preInit.unshift(mono_wasm_pre_init);
+ }
// this could be overriden on Module
- moduleExt.preInit = mono_wasm_pre_init;
- moduleExt.onRuntimeInitialized = mono_wasm_on_runtime_initialized;
+ if (!module.onRuntimeInitialized) {
+ module.onRuntimeInitialized = mono_wasm_on_runtime_initialized;
+ }
+ if (!module.print) {
+ module.print = console.log;
+ }
+ if (!module.printErr) {
+ module.printErr = console.error;
+ }
+
+ if (imports.isGlobal || !module.disableDotNet6Compatibility) {
+ Object.assign(module, api);
- if (!moduleExt.disableDotNet6Compatibility) {
// backward compatibility
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
- moduleExt.mono_bind_static_method = (fqn: string, signature: ArgsMarshalString): Function => {
+ module.mono_bind_static_method = (fqn: string, signature: ArgsMarshalString): Function => {
console.warn("Module.mono_bind_static_method is obsolete, please use BINDING.bind_static_method instead");
return mono_bind_static_method(fqn, signature);
};
// here we expose objects used in tests to global namespace
- (<any>globalThis).Module = module;
- const warnWrap = (name: string, value: any) => {
- if (typeof ((<any>globalThis)[name]) !== "undefined") {
+ const warnWrap = (name: string, provider: () => any) => {
+ if (typeof globalThisAny[name] !== "undefined") {
// it already exists in the global namespace
return;
}
- let warnOnce = true;
+ let value: any = undefined;
Object.defineProperty(globalThis, name, {
get: () => {
- if (warnOnce) {
+ if (!value) {
const stack = (new Error()).stack;
const nextLine = stack ? stack.substr(stack.indexOf("\n", 8) + 1) : "";
console.warn(`global ${name} is obsolete, please use Module.${name} instead ${nextLine}`);
- warnOnce = false;
+ value = provider();
}
return value;
}
});
};
- warnWrap("MONO", mono);
- warnWrap("BINDING", binding);
+ globalThisAny.MONO = exports.mono;
+ globalThisAny.BINDING = exports.binding;
+ globalThisAny.INTERNAL = exports.internal;
+ if (!imports.isGlobal) {
+ globalThisAny.Module = module;
+ }
// Blazor back compat
- warnWrap("cwrap", Module.cwrap);
- warnWrap("addRunDependency", Module.addRunDependency);
- warnWrap("removeRunDependency", Module.removeRunDependency);
+ warnWrap("cwrap", () => module.cwrap);
+ warnWrap("addRunDependency", () => module.addRunDependency);
+ warnWrap("removeRunDependency", () => module.removeRunDependency);
}
}
+export const __initializeImportsAndExports: any = initializeImportsAndExports; // don't want to export the type
// the methods would be visible to EMCC linker
-// --- keep in sync with library-dotnet.js ---
-const linker_exports = {
+// --- keep in sync with dotnet.lib.js ---
+export const __linker_exports: any = {
// mini-wasm.c
mono_set_timeout,
mono_wasm_load_icu_data,
mono_wasm_get_icudt_name,
};
-export const DOTNET: any = {
-};
-export const INTERNAL: any = {
+const INTERNAL: any = {
// startup
BINDING_ASM: "[System.Private.Runtime.InteropServices.JavaScript]System.Runtime.InteropServices.JavaScript.Runtime",
- export_to_emscripten,
-
- // linker
- linker_exports: linker_exports,
// tests
call_static_method,
// this represents visibility in the javascript
// like https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts
-export interface MONO {
+interface MONO {
mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready
mono_wasm_setenv: typeof mono_wasm_setenv
mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
mono_wasm_release_roots: typeof mono_wasm_release_roots;
// for Blazor's future!
- mono_wasm_add_assembly: typeof cwraps.mono_wasm_add_assembly,
- mono_wasm_load_runtime: typeof cwraps.mono_wasm_load_runtime,
+ mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number,
+ mono_wasm_load_runtime: (unused: string, debug_level: number) => void,
loaded_files: string[];
config: MonoConfig | MonoConfigError,
// this represents visibility in the javascript
// like https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts
-export interface BINDING {
+interface BINDING {
mono_obj_array_new: (size: number) => MonoArray,
mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void,
js_string_to_mono_string: typeof js_string_to_mono_string,
bind_static_method: typeof mono_bind_static_method,
call_assembly_entry_point: typeof mono_call_assembly_entry_point,
unbox_mono_obj: typeof unbox_mono_obj
+}
+export interface DotNetPublicAPI {
+ MONO: MONO,
+ BINDING: BINDING,
+ Module: any
}
\ No newline at end of file
import { EmscriptenModuleMono, MonoConfig, RuntimeHelpers } from "./types";
+// these are our public API (except internal)
export let Module: EmscriptenModule & EmscriptenModuleMono;
export let MONO: any;
export let BINDING: any;
-export let DOTNET: any;
export let INTERNAL: any;
+// these are imported and re-exported from emscripten internals
+export let ENVIRONMENT_IS_GLOBAL: boolean;
+export let ENVIRONMENT_IS_NODE: boolean;
+export let ENVIRONMENT_IS_SHELL: boolean;
+export let ENVIRONMENT_IS_WEB: boolean;
+export let locateFile: Function;
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-export function setLegacyModules(dotnet: any, mono: any, binding: any, internal: any, module: EmscriptenModule & EmscriptenModuleMono) {
- DOTNET = dotnet;
- MONO = mono;
- BINDING = binding;
- INTERNAL = internal;
- Module = module;
+export function setImportsAndExports(
+ imports: { isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function },
+ exports: { mono: any, binding: any, internal: any, module: any },
+) {
+ MONO = exports.mono;
+ BINDING = exports.binding;
+ INTERNAL = exports.internal;
+ Module = exports.module;
+ ENVIRONMENT_IS_GLOBAL = imports.isGlobal;
+ ENVIRONMENT_IS_NODE = imports.isNode;
+ ENVIRONMENT_IS_SHELL = imports.isShell;
+ ENVIRONMENT_IS_WEB = imports.isWeb;
+ locateFile = imports.locateFile;
}
let monoConfig: MonoConfig;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import { Module, runtimeHelpers } from "./modules";
+import { Module, runtimeHelpers } from "./imports";
import {
cs_owned_js_handle_symbol, get_cs_owned_object_by_js_handle, get_js_owned_object_by_gc_handle, js_owned_gc_handle_symbol,
mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle,
-/* eslint-disable no-undef */
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+/* eslint-disable no-undef */
"use strict";
$MONO: {},
$BINDING: {},
$INTERNAL: {},
- // this line will be executed on runtime, populating the objects with methods
- $DOTNET__postset: "__dotnet_runtime.INTERNAL.export_to_emscripten (DOTNET, MONO, BINDING, INTERNAL, Module);",
+ // this line will be executed early on runtime, passing import and export objects into __dotnet_runtime IFFE
+ $DOTNET__postset: "__dotnet_runtime.__initializeImportsAndExports({isGlobal:true, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile}, {mono:MONO, binding:BINDING, internal:INTERNAL, module:Module});",
};
// the methods would be visible to EMCC linker
// -- this javascript file is evaluated by emcc during compilation! --
// we generate simple proxy for each exported function so that emcc will include them in the final output
for (let linked_function of linked_functions) {
- const fn_template = `return __dotnet_runtime.INTERNAL.linker_exports.${linked_function}.apply(__dotnet_runtime, arguments)`;
+ const fn_template = `return __dotnet_runtime.__linker_exports.${linked_function}.apply(__dotnet_runtime, arguments)`;
DotNetSupportLib[linked_function] = new Function(fn_template);
}
-import { Module } from "./modules";
+import { Module } from "./imports";
const _temp_mallocs: Array<Array<VoidPtr> | null> = [];
type _MemOffset = number | VoidPtr | NativePointer;
-export function setU8 (offset: _MemOffset, value: number) : void {
+export function setU8(offset: _MemOffset, value: number): void {
Module.HEAPU8[<any>offset] = value;
}
-export function setU16 (offset: _MemOffset, value: number) : void {
+export function setU16(offset: _MemOffset, value: number): void {
Module.HEAPU16[<any>offset >>> 1] = value;
}
-export function setU32 (offset: _MemOffset, value: number) : void {
+export function setU32(offset: _MemOffset, value: number): void {
Module.HEAPU32[<any>offset >>> 2] = value;
}
-export function setI8 (offset: _MemOffset, value: number) : void {
+export function setI8(offset: _MemOffset, value: number): void {
Module.HEAP8[<any>offset] = value;
}
-export function setI16 (offset: _MemOffset, value: number) : void {
+export function setI16(offset: _MemOffset, value: number): void {
Module.HEAP16[<any>offset >>> 1] = value;
}
-export function setI32 (offset: _MemOffset, value: number) : void {
+export function setI32(offset: _MemOffset, value: number): void {
Module.HEAP32[<any>offset >>> 2] = value;
}
// NOTE: Accepts a number, not a BigInt, so values over Number.MAX_SAFE_INTEGER will be corrupted
-export function setI64 (offset: _MemOffset, value: number) : void {
+export function setI64(offset: _MemOffset, value: number): void {
Module.setValue(<VoidPtr><any>offset, value, "i64");
}
-export function setF32 (offset: _MemOffset, value: number) : void {
+export function setF32(offset: _MemOffset, value: number): void {
Module.HEAPF32[<any>offset >>> 2] = value;
}
-export function setF64 (offset: _MemOffset, value: number) : void {
+export function setF64(offset: _MemOffset, value: number): void {
Module.HEAPF64[<any>offset >>> 3] = value;
}
-export function getU8 (offset: _MemOffset) : number {
+export function getU8(offset: _MemOffset): number {
return Module.HEAPU8[<any>offset];
}
-export function getU16 (offset: _MemOffset) : number {
+export function getU16(offset: _MemOffset): number {
return Module.HEAPU16[<any>offset >>> 1];
}
-export function getU32 (offset: _MemOffset) : number {
+export function getU32(offset: _MemOffset): number {
return Module.HEAPU32[<any>offset >>> 2];
}
-export function getI8 (offset: _MemOffset) : number {
+export function getI8(offset: _MemOffset): number {
return Module.HEAP8[<any>offset];
}
-export function getI16 (offset: _MemOffset) : number {
+export function getI16(offset: _MemOffset): number {
return Module.HEAP16[<any>offset >>> 1];
}
-export function getI32 (offset: _MemOffset) : number {
+export function getI32(offset: _MemOffset): number {
return Module.HEAP32[<any>offset >>> 2];
}
// NOTE: Returns a number, not a BigInt. This means values over Number.MAX_SAFE_INTEGER will be corrupted
-export function getI64 (offset: _MemOffset) : number {
+export function getI64(offset: _MemOffset): number {
return Module.getValue(<number><any>offset, "i64");
}
-export function getF32 (offset: _MemOffset) : number {
+export function getF32(offset: _MemOffset): number {
return Module.HEAPF32[<any>offset >>> 2];
}
-export function getF64 (offset: _MemOffset) : number {
+export function getF64(offset: _MemOffset): number {
return Module.HEAPF64[<any>offset >>> 3];
}
import { WasmRoot, WasmRootBuffer, mono_wasm_new_root } from "./roots";
import { MonoClass, MonoMethod, MonoObject, coerceNull, VoidPtrNull, VoidPtr, MonoType } from "./types";
-import { BINDING, runtimeHelpers } from "./modules";
+import { BINDING, Module, runtimeHelpers } from "./imports";
import { js_to_mono_enum, _js_to_mono_obj, _js_to_mono_uri } from "./js-to-cs";
import { js_string_to_mono_string, js_string_to_mono_string_interned } from "./strings";
import { MarshalType, _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js";
-import {
- _create_temp_frame,
- getI32, getU32, getF32, getF64,
+import {
+ _create_temp_frame,
+ getI32, getU32, getF32, getF64,
setI32, setU32, setF32, setF64, setI64,
} from "./memory";
import {
MonoObjectNull, MonoString, coerceNull as coerceNull,
VoidPtr, VoidPtrNull, Int32Ptr, MonoStringNull
} from "./types";
-import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./modules";
+import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports";
import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js";
import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "./gc-handles";
import { js_array_to_mono_array, _box_js_bool, _js_to_mono_obj } from "./js-to-cs";
"version": "1.0.0",
"scripts": {
"rollup": "rollup -c",
- "lint": "eslint --no-color --max-warnings=0 ./**/*.ts ./**/*.js"
+ "lint": "eslint --no-color --max-warnings=0 ./**/*.ts ./*.js"
},
"keywords": [
"dotnet",
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import { Module } from "./modules";
+import { Module } from "./imports";
import { AOTProfilerOptions, CoverageProfilerOptions } from "./types";
// Initialize the AOT profiler with OPTIONS.
const nativeBinDir = process.env.NativeBinDir ? process.env.NativeBinDir.replace(/"/g, "") : "bin";
const terserConfig = {
compress: {
- defaults: false,// to agressive minification breaks subsequent emcc compilation
+ defaults: false,// too agressive minification breaks subsequent emcc compilation
drop_debugger: false,// we invoke debugger
drop_console: false,// we log to console
unused: false,// this breaks stuff
// below are minification features which seems to work fine
collapse_vars: true,
conditionals: true,
+ computed_props: true,
+ properties: true,
dead_code: true,
if_return: true,
inline: true,
// because of stack walk at src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs
keep_fnames: /(mono_wasm_runtime_ready|mono_wasm_fire_debugger_agent_message)/,
},
- // we export ES5 because emcc parser has trouble parsing it otherwise
- ecma: 5,
};
const plugins = isDebug ? [writeOnChangePlugin()] : [terser(terserConfig), writeOnChangePlugin()];
+const banner = "//! Licensed to the .NET Foundation under one or more agreements.\n//! The .NET Foundation licenses this file to you under the MIT license.\n";
+// emcc doesn't know how to load ES6 module, that's why we need the whole rollup.js
+const format = "iife";
+const name = "__dotnet_runtime";
export default defineConfig([
{
treeshake: !isDebug,
input: "exports.ts",
output: [{
- banner: "//! Licensed to the .NET Foundation under one or more agreements.\n//! The .NET Foundation licenses this file to you under the MIT license.\n",
- name: "__dotnet_runtime",
file: nativeBinDir + "/src/" + outputFileName,
-
- // emcc doesn't know how to load ES6 module, that's why we need the whole rollup.js
- format: "iife",
- plugins: plugins
+ name,
+ banner,
+ format,
+ plugins,
}],
plugins: [typescript()]
},
{
- input: "./exports.ts",
+ input: "./export-types.ts",
output: [
+ // dotnet.d.ts
{
format: "es",
file: nativeBinDir + "/src/" + "dotnet.d.ts",
}
],
plugins: [dts()],
- },
+ }
]);
-// this would create .md5 file next to the output file, so that we do not touch datetime of the file if it's same -> faster incremental build.
+// this would create .sha256 file next to the output file, so that we do not touch datetime of the file if it's same -> faster incremental build.
function writeOnChangePlugin() {
return {
name: "writeOnChange",
// The .NET Foundation licenses this file to you under the MIT license.
import cwraps from "./cwraps";
-import { Module } from "./modules";
+import { Module } from "./imports";
import { VoidPtr, ManagedPointer, NativePointer } from "./types";
const maxScratchRoots = 8192;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import { INTERNAL, Module, MONO, runtimeHelpers } from "./modules";
import { AllAssetEntryTypes, AssetEntry, CharPtr, CharPtrNull, EmscriptenModuleMono, GlobalizationMode, MonoConfig, VoidPtr, wasm_type_symbol } from "./types";
+import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, locateFile, Module, MONO, runtimeHelpers } from "./imports";
import cwraps from "./cwraps";
import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu";
import { bind_runtime_method, get_method, _create_primitive_converters } from "./method-binding";
import { find_corlib_class } from "./class-loader";
+export let runtime_is_initialized_resolve: Function;
+export let runtime_is_initialized_reject: Function;
+export const mono_wasm_runtime_is_initialized = new Promise((resolve, reject) => {
+ runtime_is_initialized_resolve = resolve;
+ runtime_is_initialized_reject = reject;
+});
+
+
export async function mono_wasm_pre_init(): Promise<void> {
const moduleExt = Module as EmscriptenModuleMono;
if (moduleExt.configSrc) {
- // sets MONO.config implicitly
- await mono_wasm_load_config(moduleExt.configSrc);
+ try {
+ // sets MONO.config implicitly
+ await mono_wasm_load_config(moduleExt.configSrc);
+ }
+ catch (err: any) {
+ runtime_is_initialized_reject(err);
+ throw err;
+ }
if (moduleExt.onConfigLoaded) {
try {
Module.printErr("MONO_WASM: onConfigLoaded () failed: " + err);
Module.printErr("MONO_WASM: Stacktrace: \n");
Module.printErr(err.stack);
+ runtime_is_initialized_reject(err);
throw err;
}
}
return fetch(url, { credentials: "same-origin" });
}
else if (ENVIRONMENT_IS_NODE) {
+ //const fs = (<any>globalThis).require("fs");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require("fs");
const arrayBuffer = await fs.promises.readFile(url);
- return <Response><any> {
+ return <Response><any>{
ok: true,
url,
arrayBuffer: () => arrayBuffer,
}
else if (typeof (read) === "function") {
const arrayBuffer = new Uint8Array(read(url, "binary"));
- return <Response><any> {
+ return <Response><any>{
ok: true,
url,
arrayBuffer: () => arrayBuffer,
}
}
catch (e: any) {
- return <Response><any> {
+ return <Response><any>{
ok: false,
url,
arrayBuffer: () => { throw e; },
if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) {
try {
cwraps.mono_wasm_load_runtime("unused", args.debug_level || 0);
- } catch (ex: any) {
- Module.printErr("MONO_WASM: mono_wasm_load_runtime () failed: " + ex);
+ } catch (err: any) {
+ Module.printErr("MONO_WASM: mono_wasm_load_runtime () failed: " + err);
Module.printErr("MONO_WASM: Stacktrace: \n");
- Module.printErr(ex.stack);
+ Module.printErr(err.stack);
+ runtime_is_initialized_reject(err);
const wasm_exit = cwraps.mono_wasm_exit;
wasm_exit(1);
}
mono_wasm_setenv("TZ", tz || "UTC");
mono_wasm_runtime_ready();
+ //legacy config loading
+ const argsAny: any = args;
+ if (argsAny.loaded_cb) {
+ try {
+ argsAny.loaded_cb();
+ }
+ catch (err: any) {
+ Module.printErr("MONO_WASM: loaded_cb () failed: " + err);
+ Module.printErr("MONO_WASM: Stacktrace: \n");
+ Module.printErr(err.stack);
+ runtime_is_initialized_reject(err);
+ throw err;
+ }
+ }
+
if (moduleExt.onDotNetReady) {
try {
moduleExt.onDotNetReady();
Module.printErr("MONO_WASM: onDotNetReady () failed: " + err);
Module.printErr("MONO_WASM: Stacktrace: \n");
Module.printErr(err.stack);
+ runtime_is_initialized_reject(err);
throw err;
}
}
+
+ runtime_is_initialized_resolve();
}
export function bindings_lazy_init(): void {
await Promise.all(fetch_promises);
_finalize_startup(args, ctx);
- } catch (exc: any) {
- console.error("MONO_WASM: Error in mono_load_runtime_and_bcl_args:", exc);
- throw exc;
+ } catch (err: any) {
+ console.error("MONO_WASM: Error in mono_load_runtime_and_bcl_args:", err);
+ runtime_is_initialized_reject(err);
+ throw err;
}
}
config.runtime_options = config.runtime_options || [];
config.globalization_mode = config.globalization_mode || GlobalizationMode.AUTO;
- } catch (exc) {
- const errMessage = `Failed to load config file ${configFilePath} ${exc}`;
+ } catch (err) {
+ const errMessage = `Failed to load config file ${configFilePath} ${err}`;
console.error(errMessage);
- runtimeHelpers.config = { message: errMessage, error: exc, isError: true };
- throw exc;
+ runtimeHelpers.config = { message: errMessage, error: err, isError: true };
+ runtime_is_initialized_reject(err);
+ throw err;
} finally {
Module.removeRunDependency(configFilePath);
}
import { mono_wasm_new_root_buffer, WasmRootBuffer } from "./roots";
import { CharPtr, MonoString, MonoStringNull, NativePointer } from "./types";
-import { Module } from "./modules";
+import { Module } from "./imports";
import cwraps from "./cwraps";
import { mono_wasm_new_root } from "./roots";
import { getI32 } from "./memory";
return js_string_to_mono_string_new(string);
}
-export function js_string_to_mono_string_new(string: string) : MonoString {
+export function js_string_to_mono_string_new(string: string): MonoString {
const buffer = Module._malloc((string.length + 1) * 2);
const buffer16 = (<any>buffer >>> 1) | 0;
for (let i = 0; i < string.length; i++)
"noEmitOnError": true,
"removeComments": false,
"sourceMap": false,
- "target": "ES5",
+ "target": "ES2018",
"moduleResolution": "Node",
"lib": [
"esnext",
}
// how we extended emscripten Module
-export type EmscriptenModuleMono = EmscriptenModule & {
+export type EmscriptenModuleMono = EmscriptenModule & EmscriptenModuleConfig;
+
+export type EmscriptenModuleConfig = {
disableDotNet6Compatibility?: boolean,
// backward compatibility
__brand: "CharPtrPtr"
}
-declare let ENVIRONMENT_IS_WEB: boolean;
-declare let ENVIRONMENT_IS_SHELL: boolean;
-declare let ENVIRONMENT_IS_NODE: boolean;
-declare let ENVIRONMENT_IS_WORKER: boolean;
-declare let LibraryManager: any;
-
-declare function autoAddDeps(a: object, b: string): void;
-declare function mergeInto(a: object, b: object): void;
-
-// TODO, what's wrong with EXPORTED_RUNTIME_METHODS ?
-declare function locateFile(path: string, prefix?: string): string;
-
-declare let Module: EmscriptenModule;
-
declare interface EmscriptenModule {
HEAP8: Int8Array,
HEAP16: Int16Array;
removeRunDependency(id: string): void;
addRunDependency(id: string): void;
- preInit?: () => Promise<void>;
+ preInit?: (() => Promise<void>)[];
onRuntimeInitialized?: () => void;
}
import { wrap_error } from "./method-calls";
import { conv_string } from "./strings";
import { Int32Ptr, JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString } from "./types";
+import { Module } from "./imports";
const wasm_ws_pending_send_buffer = Symbol.for("wasm ws_pending_send_buffer");
const wasm_ws_pending_send_buffer_offset = Symbol.for("wasm ws_pending_send_buffer_offset");
//glue code to deal with the differences between chrome, ch, d8, jsc and sm.
const is_browser = typeof window != "undefined";
-const is_node = !is_browser && typeof process != 'undefined';
+const is_node = !is_browser && typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
// if the engine doesn't provide a console
if (typeof (console) === "undefined") {
error: console.error
};
+let isXUnitDoneCheck = false;
+
function proxyMethod(prefix, func, asJson) {
return function () {
const args = [...arguments];
payload = payload.toString();
}
}
+ if (payload.indexOf("=== TEST EXECUTION SUMMARY ===") != -1) {
+ isXUnitDoneCheck = true;
+ }
if (asJson) {
func(JSON.stringify({
const consoleUrl = `${window.location.origin}/console`.replace('http://', 'ws://');
let consoleWebSocket = new WebSocket(consoleUrl);
- consoleWebSocket.onopen = function (event) {
- proxyJson(function (msg) {
+ // redirect output so that when emscripten starts it's already redirected
+ proxyJson(function (msg) {
+ if (consoleWebSocket.readyState === WebSocket.OPEN) {
consoleWebSocket.send(msg);
- });
- console.log("browser: Console websocket connected.");
+ }
+ else {
+ originalConsole.log(msg);
+ }
+ });
+
+ consoleWebSocket.onopen = function (event) {
+ originalConsole.log("browser: Console websocket connected.");
};
consoleWebSocket.onerror = function (event) {
- console.error(`websocket error: ${event}`);
+ originalConsole.error(`websocket error: ${event}`);
};
}
}
}
}
-
var Module = {
- no_global_exports: true,
- mainScriptUrlOrBlob: "dotnet.js",
config: null,
configSrc: "./mono-config.json",
- print: console.log,
- printErr: console.error,
- onConfigLoaded: function () {
+ onConfigLoaded: () => {
if (!Module.config) {
- console.error("Could not find ./mono-config.json. Cancelling run");
- fail_exec(1);
+ const err = new Error("Could not find ./mono-config.json. Cancelling run");
+ set_exit_code(1,);
+ throw err;
}
// Have to set env vars here to enable setting MONO_LOG_LEVEL etc.
for (let variable in processedArguments.setenv) {
INTERNAL.mono_wasm_enable_on_demand_gc(0);
}
},
- onDotNetReady: function () {
+ onDotNetReady: () => {
let wds = Module.FS.stat(processedArguments.working_dir);
if (wds === undefined || !Module.FS.isDir(wds.mode)) {
- fail_exec(1, `Could not find working directory ${processedArguments.working_dir}`);
+ set_exit_code(1, `Could not find working directory ${processedArguments.working_dir}`);
return;
}
App.init();
},
- onAbort: function (x) {
- console.log("ABORT: " + x);
+ onAbort: (error) => {
+ console.log("ABORT: " + error);
const err = new Error();
console.log("Stacktrace: \n");
console.error(err.stack);
- fail_exec(1);
+ set_exit_code(1, error);
},
};
+
const App = {
- init: function () {
+ init: async function () {
console.info("Initializing.....");
-
for (let i = 0; i < processedArguments.profilers.length; ++i) {
const init = Module.cwrap('mono_wasm_load_profiler_' + processedArguments.profilers[i], 'void', ['string']);
init("");
}
if (processedArguments.applicationArgs.length == 0) {
- fail_exec(1, "Missing required --run argument");
+ set_exit_code(1, "Missing required --run argument");
return;
}
}
if (res)
- fail_exec(1, "REGRESSION TEST FAILED");
+ set_exit_code(1, "REGRESSION TEST FAILED");
return;
}
if (processedArguments.applicationArgs[0] == "--run") {
// Run an exe
if (processedArguments.applicationArgs.length == 1) {
- fail_exec(1, "Error: Missing main executable argument.");
+ set_exit_code(1, "Error: Missing main executable argument.");
return;
}
+ try {
- const main_assembly_name = processedArguments.applicationArgs[1];
- const app_args = processedArguments.applicationArgs.slice(2);
- INTERNAL.mono_wasm_set_main_args(processedArguments.applicationArgs[1], app_args);
-
- // Automatic signature isn't working correctly
- const result = BINDING.call_assembly_entry_point(main_assembly_name, [app_args], "m");
- const onError = function (error) {
- console.error(error);
- if (error.stack)
- console.error(error.stack);
+ const main_assembly_name = processedArguments.applicationArgs[1];
+ const app_args = processedArguments.applicationArgs.slice(2);
+ INTERNAL.mono_wasm_set_main_args(processedArguments.applicationArgs[1], app_args);
- fail_exec(1);
- }
- try {
- result.then(fail_exec).catch(onError);
+ // Automatic signature isn't working correctly
+ const result = await BINDING.call_assembly_entry_point(main_assembly_name, [app_args], "m");
+ set_exit_code(result);
} catch (error) {
- onError(error);
+ set_exit_code(1, error);
}
-
} else {
- fail_exec(1, "Unhandled argument: " + processedArguments.applicationArgs[0]);
+ set_exit_code(1, "Unhandled argument: " + processedArguments.applicationArgs[0]);
}
},
};
globalThis.App = App; // Necessary as System.Runtime.InteropServices.JavaScript.Tests.MarshalTests (among others) call the App.call_test_method directly
-function fail_exec(exit_code, reason) {
+function set_exit_code(exit_code, reason) {
if (reason) {
- console.error(reason);
+ console.error(reason.toString());
+ if (reason.stack) {
+ console.error(reason.stack);
+ }
}
if (is_browser) {
+ const stack = (new Error()).stack.replace(/\n/g, "").replace(/[ ]*at/g, " at").replace(/https?:\/\/[0-9.:]*/g, "").replace("Error", "");
+ const messsage = `Exit called with ${exit_code} when isXUnitDoneCheck=${isXUnitDoneCheck} ${stack}.`;
+
// Notify the selenium script
Module.exit_code = exit_code;
- originalConsole.log("WASM EXIT " + exit_code);
+
+ //Tell xharness WasmBrowserTestRunner what was the exit code
const tests_done_elem = document.createElement("label");
tests_done_elem.id = "tests_done";
tests_done_elem.innerHTML = exit_code.toString();
document.body.appendChild(tests_done_elem);
- } else { // shell or node
+
+ // need to flush streams (stdout/stderr)
+ for (const stream of Module.FS.streams) {
+ if (stream && stream.stream_ops && stream.stream_ops.flush) {
+ stream.stream_ops.flush(stream);
+ }
+ }
+ console.log("Flushed stdout!");
+
+ console.log('1 ' + messsage);
+ setTimeout(() => {
+ originalConsole.log('2 ' + messsage);
+ // tell xharness WasmTestMessagesProcessor we are done.
+ console.log("WASM EXIT " + exit_code);
+ }, 100);
+ } else if (INTERNAL) {
INTERNAL.mono_wasm_exit(exit_code);
}
}
const arg = currentArg.substring("--setenv=".length);
const parts = arg.split('=');
if (parts.length != 2)
- fail_exec(1, "Error: malformed argument: '" + currentArg);
+ set_exit_code(1, "Error: malformed argument: '" + currentArg);
setenv[parts[0]] = parts[1];
} else if (currentArg.startsWith("--runtime-arg=")) {
const arg = currentArg.substring("--runtime-arg=".length);
async function loadDotnet(file) {
let loadScript = undefined;
if (typeof WScript !== "undefined") { // Chakra
- loadScript = WScript.LoadScriptFile;
- return globalThis.Module;
+ loadScript = function (file) {
+ WScript.LoadScriptFile(file);
+ return globalThis.Module;
+ };
} else if (is_node) { // NodeJS
loadScript = async function (file) {
return require(file);
const script = document.createElement("script");
script.src = file;
document.head.appendChild(script);
- return globalThis.Module;
+ let timeout = 100;
+ // bysy spin waiting for script to load into global namespace
+ while (timeout > 0) {
+ if (globalThis.Module) {
+ return globalThis.Module;
+ }
+ // delay 10ms
+ await new Promise(resolve => setTimeout(resolve, 10));
+ timeout--;
+ }
+ throw new Error("Can't load " + file);
}
}
else if (typeof globalThis.load !== 'undefined') {
loadDotnet("./dotnet.js").catch(function (err) {
console.error(err);
- fail_exec(1, "failed to load the dotnet.js file");
+ set_exit_code(1, "failed to load the dotnet.js file");
throw err;
});
\ No newline at end of file
if (!FileCopyChecked(item.ItemSpec, dest, "NativeAssets"))
return false;
}
- FileCopyChecked(MainJS!, Path.Combine(AppDir, "runtime.js"), string.Empty);
+ FileCopyChecked(MainJS!, Path.Combine(AppDir, "main.js"), string.Empty);
string indexHtmlPath = Path.Combine(AppDir, "index.html");
if (!File.Exists(indexHtmlPath))
{
- var html = @"<html><body><script type=""text/javascript"" src=""runtime.js""></script></body></html>";
+ var html = @"<html><body><script type=""text/javascript"" src=""main.js""></script></body></html>";
File.WriteAllText(indexHtmlPath, html);
}
string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config), "AppBundle");
(string testCommand, string extraXHarnessArgs) = host switch
{
- RunHost.V8 => ("wasm test", "--js-file=runtime.js --engine=V8 -v trace"),
+ RunHost.V8 => ("wasm test", "--js-file=main.js --engine=V8 -v trace"),
_ => ("wasm test-browser", $"-v trace -b {host}")
};
<TargetFramework>{s_targetFramework}</TargetFramework>
<OutputType>Exe</OutputType>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
- <WasmMainJSPath>runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>test-main.js</WasmMainJSPath>
##EXTRA_PROPERTIES##
</PropertyGroup>
<ItemGroup>
initProject?.Invoke();
File.WriteAllText(Path.Combine(_projectDir, $"{buildArgs.ProjectName}.csproj"), buildArgs.ProjectFileContents);
- File.Copy(Path.Combine(AppContext.BaseDirectory, "runtime-test.js"), Path.Combine(_projectDir, "runtime-test.js"));
+ File.Copy(Path.Combine(AppContext.BaseDirectory, "test-main.js"), Path.Combine(_projectDir, "test-main.js"));
}
else if (_projectDir is null)
{
AssertFilesExist(bundleDir, new []
{
"index.html",
- "runtime.js",
+ "main.js",
"dotnet.timezones.blat",
"dotnet.wasm",
"mono-config.json",
<TargetFramework>{s_targetFramework}</TargetFramework>
<OutputType>Exe</OutputType>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
- <WasmMainJSPath>runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>test-main.js</WasmMainJSPath>
##EXTRA_PROPERTIES##
</PropertyGroup>
<ItemGroup>
</PropertyGroup>
<ItemGroup>
- <None Include="$(RepoRoot)\src\mono\wasm\runtime-test.js" CopyToOutputDirectory="PreserveNewest" />
+ <None Include="$(RepoRoot)\src\mono\wasm\test-main.js" CopyToOutputDirectory="PreserveNewest" />
<None Include="..\testassets\**\*" Link="testassets\%(RecursiveDir)%(FileName)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
<None Include="data\**\*" Link="data\%(RecursiveDir)%(FileName)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
TargetDir="wasm-test-runner/"/>
<RunTimeDependencyCopyLocal
- Include="$(MonoProjectRoot)\wasm\runtime-test.js"
+ Include="$(MonoProjectRoot)\wasm\test-main.js"
TargetDir="runtime-test/"/>
<RunTimeDependencyCopyLocal
<PropertyGroup>
<WasmMainAssemblyFileName>$(TestAssemblyFileName)</WasmMainAssemblyFileName>
<WasmAppDir>$(AppDir)</WasmAppDir>
- <WasmMainJSPath>$(CORE_ROOT)\runtime-test\runtime-test.js</WasmMainJSPath>
+ <WasmMainJSPath>$(CORE_ROOT)\runtime-test\test-main.js</WasmMainJSPath>
<WasmResolveAssembliesBeforeBuild>true</WasmResolveAssembliesBeforeBuild>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
<WasmSkipMissingAssemblies>true</WasmSkipMissingAssemblies>
TargetDir="wasm-test-runner/"/>
<RunTimeDependencyCopyLocal
- Include="$(MonoProjectRoot)\wasm\runtime-test.js"
+ Include="$(MonoProjectRoot)\wasm\test-main.js"
TargetDir="runtime-test/"/>
<RunTimeDependencyCopyLocal
<TestRuntime>true</TestRuntime>
<Scenario>WasmTestOnBrowser</Scenario>
<ExpectedExitCode>42</ExpectedExitCode>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
<EnableDefaultItems>false</EnableDefaultItems>
- <!-- setting WasmXHarnessMonoArgs doesn't work here, but see runtime.js -->
+ <!-- setting WasmXHarnessMonoArgs doesn't work here, but see main.js -->
<!-- <WasmXHarnessMonoArgs>- -setenv=DOTNET_MODIFIABLE_ASSEMBLIES=debug</WasmXHarnessMonoArgs> -->
</PropertyGroup>
<ItemGroup>
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
- <head>
- <title>TESTS</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body onload="onLoad()">
- <h3 id="header">Wasm Browser Sample</h3>
- Result from Sample.Test.TestMeaning: <span id="out"></span>
- <script type='text/javascript'>
- var is_testing = false;
- var onLoad = function() {
- var url = new URL(decodeURI(window.location));
- let args = url.searchParams.getAll('arg');
- is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
- };
- var test_exit = function(exit_code)
- {
- if (!is_testing) {
- console.log(`test_exit: ${exit_code}`);
- return;
- }
+<head>
+ <title>Wasm HotReload Test</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
- /* Set result in a tests_done element, to be read by xharness */
- var tests_done_elem = document.createElement("label");
- tests_done_elem.id = "tests_done";
- tests_done_elem.innerHTML = exit_code.toString();
- document.body.appendChild(tests_done_elem);
+<body>
+ <h3 id="header">Wasm HotReload Test</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <script type='text/javascript'>
+ function set_exit_code(exit_code, reason) {
+ /* Set result in a tests_done element, to be read by xharness */
+ var tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
- console.log(`WASM EXIT ${exit_code}`);
- };
+ console.log(`WASM EXIT ${exit_code}`);
+ };
- var App = {
- init: function () {
- var exit_code = INTERNAL.call_static_method("[WebAssembly.Browser.HotReload.Test] Sample.Test:TestMeaning", []);
- document.getElementById("out").innerHTML = exit_code;
+ var App = {
+ init: function () {
+ const testMeaning = BINDING.bind_static_method("[WebAssembly.Browser.HotReload.Test] Sample.Test:TestMeaning");
+ var exit_code = testMeaning();
+ document.getElementById("out").innerHTML = exit_code;
- if (is_testing)
- {
- console.debug(`exit_code: ${exit_code}`);
- test_exit(exit_code);
- }
- },
- };
- </script>
- <script type="text/javascript" src="runtime.js"></script>
+ console.debug(`exit_code: ${exit_code}`);
+ set_exit_code(exit_code);
+ },
+ };
+ </script>
+ <script type="text/javascript" src="main.js"></script>
+ <script defer src="dotnet.js"></script>
- <script defer src="dotnet.js"></script>
+</body>
- </body>
-</html>
+</html>
\ No newline at end of file
"use strict";
var Module = {
- config: null,
configSrc: "./mono-config.json",
- onConfigLoaded: function () {
+ onConfigLoaded: () => {
MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
},
- onDotNetReady: function () {
+ onDotNetReady: () => {
try {
App.init();
} catch (error) {
- test_exit(1);
+ set_exit_code(1, error);
throw (error);
}
},
- onAbort: function () {
- test_exit(1);
+ onAbort: (error) => {
+ set_exit_code(1, error);
},
};
<TestRuntime>true</TestRuntime>
<Scenario>WasmTestOnBrowser</Scenario>
<ExpectedExitCode>42</ExpectedExitCode>
- <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainJSPath>main.js</WasmMainJSPath>
</PropertyGroup>
<ItemGroup>
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
- <head>
- <title>TESTS</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body onload="onLoad()">
- <h3 id="header">Wasm Browser Sample</h3>
- Result from Sample.Test.TestMeaning: <span id="out"></span>
- <script type='text/javascript'>
- var is_testing = false;
- var onLoad = function() {
- var url = new URL(decodeURI(window.location));
- let args = url.searchParams.getAll('arg');
- is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
- };
- var test_exit = function(exit_code)
- {
- if (!is_testing) {
- console.log(`test_exit: ${exit_code}`);
- return;
- }
+<head>
+ <title>Runtime config test</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
- /* Set result in a tests_done element, to be read by xharness */
- var tests_done_elem = document.createElement("label");
- tests_done_elem.id = "tests_done";
- tests_done_elem.innerHTML = exit_code.toString();
- document.body.appendChild(tests_done_elem);
+<body>
+ <h3 id="header">Runtime config test</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <script type='text/javascript'>
+ function set_exit_code(exit_code, reason) {
+ /* Set result in a tests_done element, to be read by xharness */
+ var tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
- console.log(`WASM EXIT ${exit_code}`);
- };
+ console.log(`WASM EXIT ${exit_code}`);
+ };
- var App = {
- init: function () {
- var exit_code = INTERNAL.call_static_method("[WebAssembly.Browser.RuntimeConfig.Test] Sample.Test:TestMeaning", []);
- document.getElementById("out").innerHTML = exit_code;
+ var App = {
+ init: function () {
+ const testMeaning = BINDING.bind_static_method("[WebAssembly.Browser.RuntimeConfig.Test] Sample.Test:TestMeaning");
+ var exit_code = testMeaning();
+ document.getElementById("out").innerHTML = exit_code;
- if (is_testing)
- {
- console.debug(`exit_code: ${exit_code}`);
- test_exit(exit_code);
- }
- },
- };
- </script>
- <script type="text/javascript" src="runtime.js"></script>
+ console.debug(`exit_code: ${exit_code}`);
+ set_exit_code(exit_code);
+ },
+ };
+ </script>
+ <script type="text/javascript" src="main.js"></script>
+ <script defer src="dotnet.js"></script>
- <script defer src="dotnet.js"></script>
+</body>
- </body>
-</html>
+</html>
\ No newline at end of file
"use strict";
var Module = {
- config: null,
configSrc: "./mono-config.json",
- onDotNetReady: function () {
+ onDotNetReady: () => {
try {
App.init();
} catch (error) {
- test_exit(1);
+ set_exit_code(1, error);
throw (error);
}
},
- onAbort: function () {
- test_exit(1);
+ onAbort: (error) => {
+ set_exit_code(1, error);
},
};