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
39 changes: 18 additions & 21 deletions src/mono/browser/runtime/loader/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ export async function mono_download_assets (): Promise<void> {

const instantiate = async (downloadPromise: Promise<AssetEntryInternal>) => {
const asset = await downloadPromise;
const headersOnly = skipBufferByAssetTypes[asset.behavior];

if (headersOnly) {
if (asset.behavior === "symbols") {
await runtimeHelpers.instantiate_symbols_asset(asset);
cleanupAsset(asset);
}
++loaderHelpers.actual_downloaded_assets_count;
return;
}
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.

if (asset.buffer) {
if (!skipInstantiateByAssetTypes[asset.behavior]) {
mono_assert(asset.buffer && typeof asset.buffer === "object", "asset buffer must be array-like or buffer-like or promise of these");
Expand All @@ -202,24 +213,12 @@ export async function mono_download_assets (): Promise<void> {
runtimeHelpers.instantiate_asset(asset, url, data);
}
} else {
const headersOnly = skipBufferByAssetTypes[asset.behavior];
if (!headersOnly) {
mono_assert(asset.isOptional, "Expected asset to have the downloaded buffer");
if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
loaderHelpers.expected_downloaded_assets_count--;
}
if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
loaderHelpers.expected_instantiated_assets_count--;
}
} else {
if (asset.behavior === "symbols") {
await runtimeHelpers.instantiate_symbols_asset(asset);
cleanupAsset(asset);
}

if (skipBufferByAssetTypes[asset.behavior]) {
++loaderHelpers.actual_downloaded_assets_count;
}
mono_assert(asset.isOptional, "Expected asset to have the downloaded buffer");
if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
loaderHelpers.expected_downloaded_assets_count--;
}
if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
loaderHelpers.expected_instantiated_assets_count--;
}
}
};
Expand Down Expand Up @@ -529,9 +528,7 @@ async function start_asset_download_sources (asset: AssetEntryInternal): Promise
ok: true,
arrayBuffer: () => buffer,
json: () => JSON.parse(new TextDecoder("utf-8").decode(buffer)),
text: () => {
throw new Error("NotImplementedException");
},
text: () => new TextDecoder("utf-8").decode(buffer),
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
headers: {
get: () => undefined,
}
Comment thread
elringus marked this conversation as resolved.
Expand Down
17 changes: 17 additions & 0 deletions src/mono/wasm/Wasm.Build.Tests/ModuleConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ public async Task AssetIntegrity()
);
}

[Fact]
public async Task BufferedAssetsTest()
{
Configuration config = Configuration.Debug;
ProjectInfo info = CopyTestAsset(
config,
aot: false,
TestAsset.WasmBasicTestApp,
"ModuleConfigTests_BufferedAssetsTest",
extraProperties: "<WasmEmitSymbolMap>true</WasmEmitSymbolMap>");
PublishProject(info, config, new PublishOptions(AssertAppBundle: false));
await RunForPublishWithWebServer(new BrowserRunOptions(
Configuration: config,
TestScenario: "BufferedAssetsTest"
));
}

[Theory]
[InlineData(false)]
[InlineData(true)]
Expand Down
23 changes: 15 additions & 8 deletions src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ public IReadOnlyDictionary<string, DotNetFileName> FindAndAssertDotnetFiles(

foreach ((string expectedFilename, bool expectFingerprint) in superSet.OrderByDescending(kvp => kvp.Key))
{
string prefix = Path.GetFileNameWithoutExtension(expectedFilename);
string extension = Path.GetExtension(expectedFilename).Substring(1);

dotnetFiles = dotnetFiles
.Where(actualFile =>
{
Expand All @@ -127,7 +124,7 @@ public IReadOnlyDictionary<string, DotNetFileName> FindAndAssertDotnetFiles(
expectFingerprintOnDotnetJs: expectFingerprintOnDotnetJs,
expectFingerprintForThisFile: expectFingerprint))
{
string pattern = $"^{prefix}{s_dotnetVersionHashRegex}{extension}$";
string pattern = GetFingerprintRegexPattern(expectedFilename);
var match = Regex.Match(actualFilename, pattern);
if (!match.Success)
return true;
Expand Down Expand Up @@ -418,6 +415,19 @@ private string[] GetFilesMatchingNameConsideringFingerprinting(string filePath,
public bool ShouldCheckFingerprint(string expectedFilename, bool? expectFingerprintOnDotnetJs, bool expectFingerprintForThisFile)
=> IsFingerprintingEnabled && ((expectedFilename == "dotnet.js" && expectFingerprintOnDotnetJs == true) || expectFingerprintForThisFile);

private static string GetFingerprintRegexPattern(string expectedFilename)
{
const string jsSymbolsSuffix = ".js.symbols";
if (expectedFilename.EndsWith(jsSymbolsSuffix, StringComparison.Ordinal))
{
string prefix = expectedFilename[..^jsSymbolsSuffix.Length];
return $"^{Regex.Escape(prefix)}{s_dotnetVersionHashRegex}js\\.symbols$";
}

string defaultPrefix = Path.GetFileNameWithoutExtension(expectedFilename);
string extension = Path.GetExtension(expectedFilename).Substring(1);
return $"^{Regex.Escape(defaultPrefix)}{s_dotnetVersionHashRegex}{Regex.Escape(extension)}$";
}
Comment thread
elringus marked this conversation as resolved.

public static void AssertRuntimePackPath(string buildOutput, string targetFramework, RuntimeVariant runtimeType = RuntimeVariant.SingleThreaded)
{
Expand Down Expand Up @@ -614,14 +624,11 @@ public BootJsonData AssertBootJson(AssertBundleOptions options)
bool expectFingerprint = knownSet[expectedFilename];
expectedEntries[expectedFilename] = item =>
{
string prefix = Path.GetFileNameWithoutExtension(expectedFilename);
string extension = Path.GetExtension(expectedFilename).Substring(1);

if (ShouldCheckFingerprint(expectedFilename: expectedFilename,
expectFingerprintOnDotnetJs: options.ExpectDotnetJsFingerprinting,
expectFingerprintForThisFile: expectFingerprint))
{
return Regex.Match(item, $"{prefix}{s_dotnetVersionHashRegex}{extension}").Success;
return Regex.Match(item, GetFingerprintRegexPattern(expectedFilename)).Success;
Comment thread
elringus marked this conversation as resolved.
}
Comment thread
elringus marked this conversation as resolved.
else
{
Expand Down
25 changes: 25 additions & 0 deletions src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,28 @@ switch (testCase) {
case "MainWithArgs":
dotnet.withApplicationArgumentsFromQuery();
break;
case "BufferedAssetsTest":
const originalFetch4 = globalThis.fetch.bind(globalThis);
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
dotnet.withModuleConfig({
onConfigLoaded: (config) => {
Comment thread
elringus marked this conversation as resolved.
const bufferedAssets = [
...config.resources.wasmNative,
...config.resources.coreAssembly,
...config.resources.assembly,
...(config.resources.corePdb ?? []),
...(config.resources.pdb ?? []),
...config.resources.wasmSymbols,
Comment thread
pavelsavara marked this conversation as resolved.
];
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
for (const asset of bufferedAssets) {
const url = new URL(asset.resolvedUrl ?? `./_framework/${asset.name}`, location.href);
asset.buffer = originalFetch4(url).then(r => {
if (!r.ok) throw new Error(`Failed to fetch buffered asset '${url}': ${r.status} ${r.statusText}`);
return r.arrayBuffer();
});
}
Comment thread
elringus marked this conversation as resolved.
Comment thread
elringus marked this conversation as resolved.
}
});
break;
}

const { setModuleImports, Module, getAssemblyExports, getConfig, INTERNAL, invokeLibraryInitializers } = await dotnet.create();
Expand Down Expand Up @@ -403,6 +425,9 @@ try {

exit(foundB && retB == 42 ? 0 : 1);

break;
case "BufferedAssetsTest":
await dotnet.runMainAndExit();
break;
default:
console.error(`Unknown test case: ${testCase}`);
Expand Down
Loading