Skip to content

Commit c763019

Browse files
authored
[wasm] Load assets earlier (#63623)
- allow Module.config to have assets with buffer instead of url - change sample to show how emscripten callbacks are triggered - pass config into onConfigLoaded and made it async - split asset download from copying it into memory - moved startup sequence to configure_emscripten_startup and documented it there - diagnostic_tracing as CLI parameter for tests - throttle parallel download of assets - move tests which fail on V8 to browser or nodeJS scenarios
1 parent d5c22b0 commit c763019

File tree

14 files changed

+276
-99
lines changed

14 files changed

+276
-99
lines changed

src/libraries/System.IO.Compression.ZipFile/tests/System.IO.Compression.ZipFile.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
55
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser</TargetFrameworks>
66
</PropertyGroup>
7+
8+
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
9+
<!-- This doesn't run on V8 shell because https://bugs.chromium.org/p/v8/issues/detail?id=12541 -->
10+
<Scenario>WasmTestOnBrowser</Scenario>
11+
<TestArchiveTestsRoot>$(TestArchiveRoot)browserornodejs/</TestArchiveTestsRoot>
12+
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
13+
<DefineConstants>$(DefineConstants);TARGET_BROWSER</DefineConstants>
14+
</PropertyGroup>
15+
716
<ItemGroup>
817
<Compile Include="ZipFile.Create.cs" />
918
<Compile Include="ZipFile.Extract.cs" />

src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser</TargetFrameworks>
44
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
55
</PropertyGroup>
6+
7+
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
8+
<!-- This doesn't run on V8 shell because https://bugs.chromium.org/p/v8/issues/detail?id=12541 -->
9+
<Scenario>WasmTestOnBrowser</Scenario>
10+
<TestArchiveTestsRoot>$(TestArchiveRoot)browserornodejs/</TestArchiveTestsRoot>
11+
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
12+
<DefineConstants>$(DefineConstants);TARGET_BROWSER</DefineConstants>
13+
</PropertyGroup>
14+
615
<ItemGroup>
716
<Compile Include="CompressionStreamUnitTests.ZLib.cs" />
817
<Compile Include="CompressionStreamUnitTests.Deflate.cs" />

src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
44
</PropertyGroup>
5+
6+
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
7+
<!-- This doesn't run on V8 shell because https://bugs.chromium.org/p/v8/issues/detail?id=12541 -->
8+
<Scenario>WasmTestOnBrowser</Scenario>
9+
<TestArchiveTestsRoot>$(TestArchiveRoot)browserornodejs/</TestArchiveTestsRoot>
10+
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
11+
<DefineConstants>$(DefineConstants);TARGET_BROWSER</DefineConstants>
12+
</PropertyGroup>
13+
514
<ItemGroup>
615
<Compile Include="Errata4.cs" />
716
<Compile Include="OutputSettings.cs" />

src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/System.Xml.Xsl.XslTransformApi.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
44
</PropertyGroup>
5+
6+
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
7+
<!-- This doesn't run on V8 shell because https://bugs.chromium.org/p/v8/issues/detail?id=12541 -->
8+
<Scenario>WasmTestOnBrowser</Scenario>
9+
<TestArchiveTestsRoot>$(TestArchiveRoot)browserornodejs/</TestArchiveTestsRoot>
10+
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
11+
<DefineConstants>$(DefineConstants);TARGET_BROWSER</DefineConstants>
12+
</PropertyGroup>
13+
514
<ItemGroup>
615
<Compile Include="cthread.cs" />
716
<Compile Include="CThreads.cs" />

src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCompiler.Tests.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
44
</PropertyGroup>
5+
6+
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
7+
<!-- This doesn't run on V8 shell because https://bugs.chromium.org/p/v8/issues/detail?id=12541 -->
8+
<Scenario>WasmTestOnBrowser</Scenario>
9+
<TestArchiveTestsRoot>$(TestArchiveRoot)browserornodejs/</TestArchiveTestsRoot>
10+
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
11+
<DefineConstants>$(DefineConstants);TARGET_BROWSER</DefineConstants>
12+
</PropertyGroup>
13+
514
<ItemGroup>
615
<Compile Include="CommonScenarios\XsltcTestBasicFunctionality.cs" />
716
<Compile Include="CommonScenarios\XsltcTestCaseBase.cs" />

src/libraries/sendtohelixhelp.proj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@
492492
<_WorkItem Include="$(WorkItemArchiveWildCard)" Exclude="$(HelixCorrelationPayload)" />
493493

494494
<_WorkItem Include="$(TestArchiveRoot)browseronly/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" />
495+
<_WorkItem Include="$(TestArchiveRoot)browserornodejs/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" />
496+
<_WorkItem Include="$(TestArchiveRoot)browserornodejs/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnNodeJs'" />
497+
<_WorkItem Include="$(TestArchiveRoot)nodejsonly/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnNodeJs'" />
495498

496499
<HelixWorkItem Include="@(_WorkItem -> '$(WorkItemPrefix)%(FileName)')" Condition="'$(DefaultHelixWorkItems)' == 'true'">
497500
<PayloadArchive>%(Identity)</PayloadArchive>

src/libraries/tests.proj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,6 @@ Roslyn4.0.Tests.csproj" />
325325

326326
<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(BrowserHost)' == 'windows' and '$(RunDisabledWasmTestsOnWindows)' != 'true'">
327327
<!-- Issue: https://github.com/dotnet/runtime/issues/52138 -->
328-
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.IO.Compression\tests\System.IO.Compression.Tests.csproj" />
329-
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.IO.Compression.ZipFile\tests\System.IO.Compression.ZipFile.Tests.csproj" />
330-
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Private.Xml\tests\Xslt\XslCompiledTransformApi\System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj" />
331328
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\console-v8-es6\Wasm.Console.V8.ES6.Sample.csproj" />
332329
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\console-v8-cjs\Wasm.Console.V8.CJS.Sample.csproj" />
333330
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\console-node-es6\Wasm.Console.Node.ES6.Sample.csproj" />

src/mono/sample/wasm/browser/main.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,18 @@ async function loadRuntime() {
1717
async function main() {
1818
try {
1919
const createDotnetRuntime = await loadRuntime();
20-
const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => ({
21-
disableDotnet6Compatibility: true,
22-
configSrc: "./mono-config.json",
23-
}));
20+
const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => {
21+
console.log('user code in createDotnetRuntime')
22+
return {
23+
disableDotnet6Compatibility: true,
24+
configSrc: "./mono-config.json",
25+
preInit: () => { console.log('user code Module.preInit') },
26+
preRun: () => { console.log('user code Module.preRun') },
27+
onRuntimeInitialized: () => { console.log('user code Module.onRuntimeInitialized') },
28+
postRun: () => { console.log('user code Module.postRun') },
29+
}
30+
});
31+
console.log('after createDotnetRuntime')
2432

2533
const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning");
2634
const ret = testMeaning();

src/mono/wasm/runtime/dotnet.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ declare type AssetEntry = {
155155
culture?: string;
156156
load_remote?: boolean;
157157
is_optional?: boolean;
158+
buffer?: ArrayBuffer;
158159
};
159160
interface AssemblyEntry extends AssetEntry {
160161
name: "assembly";
@@ -196,7 +197,7 @@ declare type DotnetModuleConfig = {
196197
config?: MonoConfig | MonoConfigError;
197198
configSrc?: string;
198199
scriptDirectory?: string;
199-
onConfigLoaded?: () => void;
200+
onConfigLoaded?: (config: MonoConfig) => Promise<void>;
200201
onDotnetReady?: () => void;
201202
imports?: DotnetModuleConfigImports;
202203
} & Partial<EmscriptenModule>;

src/mono/wasm/runtime/exports.ts

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ import {
3131
mono_load_runtime_and_bcl_args, mono_wasm_load_config,
3232
mono_wasm_setenv, mono_wasm_set_runtime_options,
3333
mono_wasm_load_data_archive, mono_wasm_asm_loaded,
34-
mono_wasm_pre_init,
35-
mono_wasm_runtime_is_initialized,
36-
mono_wasm_on_runtime_initialized
34+
configure_emscripten_startup
3735
} from "./startup";
3836
import { mono_set_timeout, schedule_background_exec } from "./scheduling";
3937
import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu";
@@ -66,7 +64,7 @@ import {
6664
import { create_weak_ref } from "./weak-ref";
6765
import { fetch_like, readAsync_like } from "./polyfills";
6866
import { EmscriptenModule } from "./types/emscripten";
69-
import { mono_on_abort, mono_run_main, mono_run_main_and_exit } from "./run";
67+
import { mono_run_main, mono_run_main_and_exit } from "./run";
7068

7169
const MONO = {
7270
// current "public" MONO API
@@ -163,18 +161,6 @@ function initializeImportsAndExports(
163161
module.configSrc = "./mono-config.json";
164162
}
165163

166-
// these could be overriden on DotnetModuleConfig
167-
if (!module.preInit) {
168-
module.preInit = [];
169-
} else if (typeof module.preInit === "function") {
170-
module.preInit = [module.preInit];
171-
}
172-
if (!module.preRun) {
173-
module.preRun = [];
174-
} else if (typeof module.preRun === "function") {
175-
module.preRun = [module.preRun];
176-
}
177-
178164
if (!module.print) {
179165
module.print = console.log.bind(console);
180166
}
@@ -254,37 +240,6 @@ function initializeImportsAndExports(
254240
warnWrap("removeRunDependency", () => module.removeRunDependency);
255241
}
256242

257-
// this is registration of the runtime pre_init, when user set configSrc
258-
if (module.configSrc) {
259-
module.preInit.push(async () => {
260-
module.addRunDependency("mono_wasm_pre_init");
261-
// execution order == [0] ==
262-
await mono_wasm_pre_init();
263-
module.removeRunDependency("mono_wasm_pre_init");
264-
});
265-
}
266-
267-
// if onRuntimeInitialized is set it's probably Blazor, we let them to do their own init sequence
268-
if (!module.onRuntimeInitialized) {
269-
// note this would keep running in async-parallel with emscripten's `run()` and `postRun()`
270-
// because it's loading files asynchronously and the emscripten is not awaiting onRuntimeInitialized
271-
// execution order == [1] ==
272-
module.onRuntimeInitialized = () => mono_wasm_on_runtime_initialized();
273-
274-
module.ready = module.ready.then(async () => {
275-
// mono_wasm_runtime_is_initialized is set when finalize_startup is done
276-
await mono_wasm_runtime_is_initialized;
277-
// TODO we could take over Module.postRun and call it from here if necessary
278-
279-
// execution order == [2] ==
280-
return exportedAPI;
281-
});
282-
}
283-
284-
if (!module.onAbort) {
285-
module.onAbort = () => mono_on_abort;
286-
}
287-
288243
// this code makes it possible to find dotnet runtime on a page via global namespace, even when there are multiple runtimes at the same time
289244
let list: RuntimeList;
290245
if (!globalThisAny.getDotnetRuntime) {
@@ -296,6 +251,8 @@ function initializeImportsAndExports(
296251
}
297252
list.registerRuntime(exportedAPI);
298253

254+
configure_emscripten_startup(module, exportedAPI);
255+
299256
return exportedAPI;
300257
}
301258

src/mono/wasm/runtime/polyfills.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export async function fetch_like(url: string): Promise<Response> {
2121
};
2222
}
2323
else if (typeof (read) === "function") {
24+
// note that it can't open files with unicode names, like Straße.xml
25+
// https://bugs.chromium.org/p/v8/issues/detail?id=12541
2426
const arrayBuffer = new Uint8Array(read(url, "binary"));
2527
return <Response><any>{
2628
ok: true,

0 commit comments

Comments
 (0)