From: Pavel Savara Date: Wed, 15 Mar 2023 10:02:51 +0000 (+0100) Subject: [browser] new EmccEnableAssertions and EmccEnvironment MSBuild props (#82954) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~3470 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cacf5ac6fa6fa10b61176308a941df310c361f5b;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [browser] new EmccEnableAssertions and EmccEnvironment MSBuild props (#82954) * EmccEnableAssertions and EmccEnvironment MSBuild props * symbols as separate asset type Co-authored-by: Ankit Jain Co-authored-by: Marek FiĊĦera --- diff --git a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj index 11eac88..9379e71 100644 --- a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj +++ b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj @@ -4,6 +4,9 @@ true true true + true + true + web -s USE_CLOSURE_COMPILER=1 -s LEGACY_GL_EMULATION=1 -lGL -lSDL -lidbfs.js diff --git a/src/mono/wasi/build/WasiApp.Native.targets b/src/mono/wasi/build/WasiApp.Native.targets index 95cd07c..03a62b7 100644 --- a/src/mono/wasi/build/WasiApp.Native.targets +++ b/src/mono/wasi/build/WasiApp.Native.targets @@ -291,8 +291,6 @@ - - diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index d0837e1..7aa3cb7 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -170,7 +170,6 @@ <_WasmDevel Condition="'$(_WasmDevel)' == '' and '$(WasmBuildNative)' == 'true' and '$(Configuration)' == 'Debug'">true - <_EmccAssertionLevelDefault Condition="'$(_EmccAssertionLevelDefault)' == ''">0 <_EmccOptimizationFlagDefault Condition="'$(_WasmDevel)' == 'true'">-O0 <_EmccOptimizationFlagDefault Condition="'$(_EmccOptimizationFlagDefault)' == '' and '$(Configuration)' == 'Debug' and '$(WasmBuildingForNestedPublish)' != 'true'">-O1 <_EmccOptimizationFlagDefault Condition="'$(_EmccOptimizationFlagDefault)' == ''">-Oz @@ -209,7 +208,6 @@ <_EmccCFlags Include="$(EmccCompileOptimizationFlag)" /> - <_EmccCFlags Include="-s ASSERTIONS=$(_EmccAssertionLevelDefault)" Condition="'$(_WasmDevel)' == 'true'" /> <_EmccCFlags Include="@(_EmccCommonFlags)" /> <_EmccCFlags Include="-DDISABLE_PERFTRACING_LISTEN_PORTS=1" /> @@ -227,7 +225,6 @@ <_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" /> - <_EmccLDFlags Include="-s ASSERTIONS=$(_EmccAssertionLevelDefault)" Condition="'$(_WasmDevel)' == 'true'" /> <_EmccLDFlags Include="@(_EmccCommonFlags)" /> <_DriverCDependencies Include="$(_WasmPInvokeHPath);$(_WasmICallTablePath)" /> @@ -416,14 +413,18 @@ <_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-js.a <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-js.a <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a + <_EmccExportedLibraryFunction>"[@(EmccExportedLibraryFunction -> '%27%(Identity)%27', ',')]" <_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]" <_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',') + <_EmccLDSFlags Include="-s INITIAL_MEMORY=$(EmccInitialHeapSize)" /> <_EmccLDSFlags Include="-s STACK_SIZE=$(EmccStackSize)" /> <_EmccLDSFlags Include="-s WASM_BIGINT=1" /> + <_EmccLDSFlags Condition="'$(EmccEnvironment)' != ''" Include="-s ENVIRONMENT="$(EmccEnvironment)"" /> + <_EmccLDSFlags Condition="'$(EmccEnableAssertions)' == 'true'" Include="-s ASSERTIONS=1" /> <_WasmNativeFileForLinking Include="%(_BitcodeFile.ObjectFile)" /> <_WasmNativeFileForLinking Include="%(_WasmSourceFileToCompile.ObjectFile)" /> @@ -449,6 +450,7 @@ <_EmccLinkStepArgs Include="-o "$(_WasmIntermediateOutputPath)dotnet.js"" /> <_WasmLinkDependencies Include="$(_EmccLinkRsp)" /> + <_EmccLinkStepArgs Include="-s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=$(_EmccExportedLibraryFunction)" Condition="'$(_EmccExportedLibraryFunction)' != ''" /> <_EmccLinkStepArgs Include="-s EXPORTED_RUNTIME_METHODS=$(_EmccExportedRuntimeMethods)" /> <_EmccLinkStepArgs Include="-s EXPORTED_FUNCTIONS=$(_EmccExportedFunctions)" /> diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index b5ab71e..796a223 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -49,6 +49,8 @@ - $(EmccFlags) - Emcc flags used for both compiling native files, and linking - $(EmccExtraLDFlags) - Extra emcc flags for linking - $(EmccExtraCFlags) - Extra emcc flags for compiling native files + - $(EmccEnableAssertions) - Corresponds to `ASSERTIONS` arg for emcc. Default false. + - $(EmccEnvironment) - Corresponds to `ENVIRONMENT` arg for emcc. Default is `web,webview,worker,node,shell`. - $(EmccInitialHeapSize) - Initial heap size specified with `emcc`. Default value: 16777216 or size of the DLLs, whichever is larger. Corresponds to `-s INITIAL_MEMORY=...` emcc arg. (previously named EmccTotalMemory, which is still kept as an alias) @@ -90,6 +92,7 @@ - @(EmccExportedRuntimeMethod) - Extra method for emcc flag EXPORTED_RUNTIME_METHODS + - @(EmccExportedLibraryFunction) - Extra method for emcc flag DEFAULT_LIBRARY_FUNCS_TO_INCLUDE - @(EmccExportedFunction) - Extra function for emcc flag EXPORTED_FUNCTIONS --> @@ -341,7 +344,6 @@ Condition="'$(WasmEmitSymbolMap)' == 'true' and '$(_HasDotnetJsSymbols)' != 'true' and Exists('$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.js.symbols')" /> - diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index 2852e1f..b829f03 100644 --- a/src/mono/wasm/runtime/assets.ts +++ b/src/mono/wasm/runtime/assets.ts @@ -4,6 +4,7 @@ import cwraps from "./cwraps"; import { mono_wasm_load_icu_data } from "./icu"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; +import { parseSymbolMapFile } from "./logging"; import { mono_wasm_load_bytes_into_heap } from "./memory"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; import { createPromiseController, PromiseAndController } from "./promise-controller"; @@ -36,6 +37,7 @@ const skipBufferByAssetTypes: { [k: string]: boolean } = { "dotnetwasm": true, + "symbols": true, }; const containedInSnapshotByAssetTypes: { @@ -57,6 +59,7 @@ const skipInstantiateByAssetTypes: { } = { "js-module-threads": true, "dotnetwasm": true, + "symbols": true, }; export function shouldLoadIcuAsset(asset: AssetEntryInternal): boolean { @@ -119,9 +122,7 @@ export async function mono_download_assets(): Promise { countAndStartDownload(asset); } else { // Otherwise cleanup in case we were given pending download. It would be even better if we could abort the download. - asset.pendingDownloadInternal = null as any; // GC - asset.pendingDownload = null as any; // GC - asset.buffer = null as any; // GC + cleanupAsset(asset); // tell the debugger it is loaded if (asset.behavior == "resource" || asset.behavior == "assembly" || asset.behavior == "pdb") { const url = resolve_path(asset, ""); @@ -144,15 +145,17 @@ export async function mono_download_assets(): Promise { const url = asset.pendingDownloadInternal!.url; mono_assert(asset.buffer && typeof asset.buffer === "object", "asset buffer must be array or buffer like"); const data = new Uint8Array(asset.buffer!); - asset.pendingDownloadInternal = null as any; // GC - asset.pendingDownload = null as any; // GC - asset.buffer = null as any; // GC + cleanupAsset(asset); // wait till after onRuntimeInitialized and after memory snapshot is loaded or skipped await memorySnapshotSkippedOrDone.promise; await beforeOnRuntimeInitialized.promise; _instantiate_asset(asset, url, data); } + if (asset.behavior === "symbols") { + await instantiate_symbols_asset(asset); + cleanupAsset(asset); + } } else { const headersOnly = skipBufferByAssetTypes[asset.behavior]; if (!headersOnly) { @@ -415,6 +418,7 @@ function _instantiate_asset(asset: AssetEntry, url: string, bytes: Uint8Array) { switch (asset.behavior) { case "dotnetwasm": case "js-module-threads": + case "symbols": // do nothing break; case "resource": @@ -516,6 +520,18 @@ export async function instantiate_wasm_asset( successCallback(compiledInstance, compiledModule); } +export async function instantiate_symbols_asset( + pendingAsset: AssetEntryInternal, +): Promise { + try { + const response = await pendingAsset.pendingDownloadInternal!.response; + const text = await response.text(); + parseSymbolMapFile(text); + } catch (error: any) { + console.log(`MONO_WASM: Error loading symbol file ${pendingAsset.name}: ${JSON.stringify(error)}`); + } +} + // used from Blazor export function mono_wasm_load_data_archive(data: Uint8Array, prefix: string): boolean { if (data.length < 8) @@ -580,3 +596,10 @@ export async function wait_for_all_assets() { export function mono_wasm_get_loaded_files(): string[] { return runtimeHelpers.loadedFiles; } + +export function cleanupAsset(asset: AssetEntryInternal) { + // give GC chance to collect resources + asset.pendingDownloadInternal = null as any; // GC + asset.pendingDownload = null as any; // GC + asset.buffer = null as any; // GC +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index d80c3a4..f315031 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -59,7 +59,6 @@ declare interface EmscriptenModule { UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string; FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string; FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string; - FS_readFile(filename: string, opts: any): any; addFunction(fn: Function, signature: string): number; stackSave(): VoidPtr; stackRestore(stack: VoidPtr): void; @@ -178,7 +177,7 @@ interface AssetEntry extends ResourceRequest { */ pendingDownload?: LoadingResource; } -type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm" | "js-module-threads"; +type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm" | "js-module-threads" | "symbols"; type GlobalizationMode = "icu" | // load ICU globalization data from any runtime assets with behavior "icu". "invariant" | // operate in invariant globalization mode. "auto"; diff --git a/src/mono/wasm/runtime/jiterpreter-jit-call.ts b/src/mono/wasm/runtime/jiterpreter-jit-call.ts index e84fc62..8cc2d23 100644 --- a/src/mono/wasm/runtime/jiterpreter-jit-call.ts +++ b/src/mono/wasm/runtime/jiterpreter-jit-call.ts @@ -156,6 +156,9 @@ class TrampolineInfo { } } +// this is cached replacements for Module.getWasmTableEntry(); +// we could add and +// if we need to export the original function getWasmTableEntry (index: number) { let result = fnCache[index]; if (!result) { @@ -172,8 +175,6 @@ function getWasmTableEntry (index: number) { export function mono_interp_invoke_wasm_jit_call_trampoline ( thunkIndex: number, ret_sp: number, sp: number, ftndesc: number, thrown: NativePointer ) { - // FIXME: It's impossible to get emscripten to export this for some reason - // const thunk = Module.getWasmTableEntry(thunkIndex); const thunk = getWasmTableEntry(thunkIndex); try { thunk(ret_sp, sp, ftndesc, thrown); diff --git a/src/mono/wasm/runtime/logging.ts b/src/mono/wasm/runtime/logging.ts index fb8cb01..a4420b0 100644 --- a/src/mono/wasm/runtime/logging.ts +++ b/src/mono/wasm/runtime/logging.ts @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import BuildConfiguration from "consts:configuration"; import { INTERNAL, Module, runtimeHelpers } from "./imports"; import { CharPtr, VoidPtr } from "./types/emscripten"; -const wasm_func_map = new Map(); +export const wasm_func_map = new Map(); const regexes: any[] = []; // V8 @@ -183,31 +182,15 @@ export function setup_proxy_console(id: string, console: Console, origin: string anyConsole[m] = proxyConsoleMethod(`console.${m}`, send, true); } -export function readSymbolMapFile(filename: string): void { - if (runtimeHelpers.mono_wasm_symbols_are_ready) return; - runtimeHelpers.mono_wasm_symbols_are_ready = true; - try { - const res = Module.FS_readFile(filename, { flags: "r", encoding: "utf8" }); - res.split(/[\r\n]/).forEach((line: string) => { - const parts: string[] = line.split(/:/); - if (parts.length < 2) - return; - - parts[1] = parts.splice(1).join(":"); - wasm_func_map.set(Number(parts[0]), parts[1]); - }); - if (BuildConfiguration === "Debug") { - console.debug(`MONO_WASM: Loaded ${wasm_func_map.size} symbols`); - } - } catch (error: any) { - if (error.errno == 44) {// NOENT - if (BuildConfiguration === "Debug") { - console.debug(`MONO_WASM: Could not find symbols file ${filename}. Ignoring.`); - } - } - else { - console.log(`MONO_WASM: Error loading symbol file ${filename}: ${JSON.stringify(error)}`); - } - return; - } -} +export function parseSymbolMapFile(text: string) { + text.split(/[\r\n]/).forEach((line: string) => { + const parts: string[] = line.split(/:/); + if (parts.length < 2) + return; + + parts[1] = parts.splice(1).join(":"); + wasm_func_map.set(Number(parts[0]), parts[1]); + }); + + if (runtimeHelpers.diagnosticTracing) console.debug(`MONO_WASM: Loaded ${wasm_func_map.size} symbols`); +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 970a840..fc795d9 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -21,7 +21,6 @@ import { init_managed_exports } from "./managed-exports"; import { cwraps_internal } from "./exports-internal"; import { CharPtr, InstantiateWasmCallBack, InstantiateWasmSuccessCallback } from "./types/emscripten"; import { instantiate_wasm_asset, mono_download_assets, resolve_asset_path, start_asset_download, wait_for_all_assets } from "./assets"; -import { readSymbolMapFile } from "./logging"; import { mono_wasm_init_diagnostics } from "./diagnostics"; import { preAllocatePThreadWorkerPool, instantiateWasmPThreadWorkerPool } from "./pthreads/browser"; import { export_linker } from "./exports-linker"; @@ -267,7 +266,6 @@ async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) { bindings_init(); if (!runtimeHelpers.mono_wasm_runtime_is_ready) mono_wasm_runtime_ready(); - if (!runtimeHelpers.mono_wasm_symbols_are_ready) readSymbolMapFile("dotnet.js.symbols"); setTimeout(() => { // when there are free CPU cycles diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index cd8b63d..a1be576 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -206,6 +206,7 @@ export type AssetBehaviours = | "vfs" // load asset into the virtual filesystem (for fopen, File.Open, etc) | "dotnetwasm" // the binary of the dotnet runtime | "js-module-threads" // the javascript module for threads + | "symbols" // the symbols for the wasm native code export type RuntimeHelpers = { runtime_interop_module: MonoAssembly; @@ -216,7 +217,6 @@ export type RuntimeHelpers = { _i52_error_scratch_buffer: Int32Ptr; mono_wasm_runtime_is_ready: boolean; mono_wasm_bindings_is_ready: boolean; - mono_wasm_symbols_are_ready: boolean; loaded_files: string[]; maxParallelDownloads: number; diff --git a/src/mono/wasm/runtime/types/emscripten.ts b/src/mono/wasm/runtime/types/emscripten.ts index cc8ac64..7c50845 100644 --- a/src/mono/wasm/runtime/types/emscripten.ts +++ b/src/mono/wasm/runtime/types/emscripten.ts @@ -50,7 +50,6 @@ export declare interface EmscriptenModule { UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string; FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string; FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string; - FS_readFile(filename: string, opts: any): any; addFunction(fn: Function, signature: string): number; stackSave(): VoidPtr; stackRestore(stack: VoidPtr): void; diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 76cab4d..9755e40 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -197,9 +197,7 @@ - - @@ -272,6 +270,7 @@ + <_EmccExportedLibraryFunction>"[@(EmccExportedLibraryFunction -> '%27%(Identity)%27', ',')]" <_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]" <_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',') 16777216 @@ -290,6 +289,7 @@ <_EmccLinkFlags Include="-s ALLOW_TABLE_GROWTH=1" /> <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> + <_EmccLinkFlags Condition="'$(_EmccExportedLibraryFunction)' != ''" Include="-s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=$(_EmccExportedLibraryFunction)" /> <_EmccLinkFlags Include="-s EXPORTED_RUNTIME_METHODS=$(_EmccExportedRuntimeMethods)" /> <_EmccLinkFlags Include="-s EXPORTED_FUNCTIONS=$(_EmccExportedFunctions)" /> <_EmccLinkFlags Include="--source-map-base http://example.com" /> @@ -375,7 +375,7 @@ -g -Os -s -DDEBUG=1 -DENABLE_AOT_PROFILER=1 -DENABLE_BROWSER_PROFILER=1 -Oz -DENABLE_BROWSER_PROFILER=1 - $(CMakeConfigurationEmccFlags) + $(CMakeConfigurationEmccFlags) -s ASSERTIONS=1 -O2 $(CMakeConfigurationLinkFlags) -s EXPORT_ES6=1 diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index c74b581..7d9b47c 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -116,6 +116,11 @@ public class WasmAppBuilder : WasmAppBuilderBaseTask public bool LoadRemote { get; set; } } + private sealed class SymbolsData : AssetEntry + { + public SymbolsData(string name, string hash) : base(name, hash, "symbols") {} + } + protected override bool ValidateArguments() { if (!base.ValidateArguments()) @@ -198,6 +203,10 @@ public class WasmAppBuilder : WasmAppBuilderBaseTask { config.Assets.Add(new ThreadsWorkerEntry (name, Utils.ComputeIntegrity(item.ItemSpec))); } + else if(name == "dotnet.js.symbols") + { + config.Assets.Add(new SymbolsData(name, Utils.ComputeIntegrity(item.ItemSpec))); + } } string packageJsonPath = Path.Combine(AppDir, "package.json");