<EnableAggressiveTrimming>true</EnableAggressiveTrimming>
<PublishTrimmed>true</PublishTrimmed>
<WasmEnableWebcil>true</WasmEnableWebcil>
+ <WasmEmitSymbolMap>true</WasmEmitSymbolMap>
+ <EmccEnableAssertions>true</EmccEnableAssertions>
+ <EmccEnvironment>web</EmccEnvironment>
<!-- add OpenGL emulation -->
<EmccExtraLDFlags> -s USE_CLOSURE_COMPILER=1 -s LEGACY_GL_EMULATION=1 -lGL -lSDL -lidbfs.js</EmccExtraLDFlags>
<!-- just to prove we don't do JS eval() -->
<!--<_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-js.a</_WasmEHLib>-->
<!--<_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-js.a</_WasmEHLibToExclude>-->
<!--<_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a</_WasmEHLibToExclude>-->
- <!--<_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]"</_EmccExportedRuntimeMethods>-->
- <!--<_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',')</_EmccExportedFunctions>-->
<!--</PropertyGroup>-->
<!--<ItemGroup>-->
<!--[> order matters <]-->
<_WasmDevel Condition="'$(_WasmDevel)' == '' and '$(WasmBuildNative)' == 'true' and '$(Configuration)' == 'Debug'">true</_WasmDevel>
- <_EmccAssertionLevelDefault Condition="'$(_EmccAssertionLevelDefault)' == ''">0</_EmccAssertionLevelDefault>
<_EmccOptimizationFlagDefault Condition="'$(_WasmDevel)' == 'true'">-O0</_EmccOptimizationFlagDefault>
<_EmccOptimizationFlagDefault Condition="'$(_EmccOptimizationFlagDefault)' == '' and '$(Configuration)' == 'Debug' and '$(WasmBuildingForNestedPublish)' != 'true'">-O1</_EmccOptimizationFlagDefault>
<_EmccOptimizationFlagDefault Condition="'$(_EmccOptimizationFlagDefault)' == ''">-Oz</_EmccOptimizationFlagDefault>
<!-- Adding optimization flag at the top, so it gets precedence -->
<_EmccCFlags Include="$(EmccCompileOptimizationFlag)" />
- <_EmccCFlags Include="-s ASSERTIONS=$(_EmccAssertionLevelDefault)" Condition="'$(_WasmDevel)' == 'true'" />
<_EmccCFlags Include="@(_EmccCommonFlags)" />
<_EmccCFlags Include="-DDISABLE_PERFTRACING_LISTEN_PORTS=1" />
<!-- Adding optimization flag at the top, so it gets precedence -->
<_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" />
- <_EmccLDFlags Include="-s ASSERTIONS=$(_EmccAssertionLevelDefault)" Condition="'$(_WasmDevel)' == 'true'" />
<_EmccLDFlags Include="@(_EmccCommonFlags)" />
<_DriverCDependencies Include="$(_WasmPInvokeHPath);$(_WasmICallTablePath)" />
<_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-js.a</_WasmEHLib>
<_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-js.a</_WasmEHLibToExclude>
<_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a</_WasmEHLibToExclude>
+ <_EmccExportedLibraryFunction>"[@(EmccExportedLibraryFunction -> '%27%(Identity)%27', ',')]"</_EmccExportedLibraryFunction>
<_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]"</_EmccExportedRuntimeMethods>
<_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',')</_EmccExportedFunctions>
</PropertyGroup>
<ItemGroup>
<!-- order matters -->
+ <!-- some flags will be duplicated on the commandline and in the .rsp file. The last wins. -->
<_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)" />
<_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)" />
- $(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)
<WasmExtraConfig Include="string_val" Value=""abc"" />
<WasmExtraConfig Include="string_with_json" Value=""{ "abc": 4 }"" />
- @(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
-->
Condition="'$(WasmEmitSymbolMap)' == 'true' and
'$(_HasDotnetJsSymbols)' != 'true' and
Exists('$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.js.symbols')" />
- <WasmFilesToIncludeInFileSystem Include="@(WasmNativeAsset)" Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js.symbols'" />
</ItemGroup>
<ItemGroup Condition="'$(InvariantGlobalization)' != 'true'">
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";
[k: string]: boolean
} = {
"dotnetwasm": true,
+ "symbols": true,
};
const containedInSnapshotByAssetTypes: {
} = {
"js-module-threads": true,
"dotnetwasm": true,
+ "symbols": true,
};
export function shouldLoadIcuAsset(asset: AssetEntryInternal): boolean {
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, "");
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) {
switch (asset.behavior) {
case "dotnetwasm":
case "js-module-threads":
+ case "symbols":
// do nothing
break;
case "resource":
successCallback(compiledInstance, compiledModule);
}
+export async function instantiate_symbols_asset(
+ pendingAsset: AssetEntryInternal,
+): Promise<void> {
+ 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)
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
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;
*/
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";
}
}
+// this is cached replacements for Module.getWasmTableEntry();
+// we could add <EmccExportedLibraryFunction Include="$getWasmTableEntry" /> and <EmccExportedRuntimeMethod Include="getWasmTableEntry" />
+// if we need to export the original
function getWasmTableEntry (index: number) {
let result = fnCache[index];
if (!result) {
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 = <Function>Module.getWasmTableEntry(thunkIndex);
const thunk = <Function>getWasmTableEntry(thunkIndex);
try {
thunk(ret_sp, sp, ftndesc, thrown);
// 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<number, string>();
+export const wasm_func_map = new Map<number, string>();
const regexes: any[] = [];
// V8
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
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";
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
| "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;
_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;
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;
<EmccExportedRuntimeMethod Include="FS_createDataFile" />
<EmccExportedRuntimeMethod Include="removeRunDependency" />
<EmccExportedRuntimeMethod Include="addRunDependency" />
- <EmccExportedRuntimeMethod Include="FS_readFile" />
<EmccExportedRuntimeMethod Include="addFunction" />
- <EmccExportedRuntimeMethod Include="getWasmTableEntry" />
<EmccExportedFunction Include="_malloc" />
<EmccExportedFunction Include="_memalign" />
<EmccExportedFunction Include="_free" />
</ItemGroup>
<PropertyGroup>
+ <_EmccExportedLibraryFunction>"[@(EmccExportedLibraryFunction -> '%27%(Identity)%27', ',')]"</_EmccExportedLibraryFunction>
<_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]"</_EmccExportedRuntimeMethods>
<_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',')</_EmccExportedFunctions>
<EmccInitialHeapSize>16777216</EmccInitialHeapSize>
<_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" />
<CMakeConfigurationEmccFlags Condition="'$(Configuration)' == 'Debug'">-g -Os -s -DDEBUG=1 -DENABLE_AOT_PROFILER=1 -DENABLE_BROWSER_PROFILER=1</CMakeConfigurationEmccFlags>
<CMakeConfigurationEmccFlags Condition="'$(Configuration)' == 'Release'">-Oz -DENABLE_BROWSER_PROFILER=1</CMakeConfigurationEmccFlags>
- <CMakeConfigurationLinkFlags Condition="'$(Configuration)' == 'Debug'" >$(CMakeConfigurationEmccFlags)</CMakeConfigurationLinkFlags>
+ <CMakeConfigurationLinkFlags Condition="'$(Configuration)' == 'Debug'" >$(CMakeConfigurationEmccFlags) -s ASSERTIONS=1 </CMakeConfigurationLinkFlags>
<CMakeConfigurationLinkFlags Condition="'$(Configuration)' == 'Release'">-O2</CMakeConfigurationLinkFlags>
<CMakeConfigurationLinkFlags>$(CMakeConfigurationLinkFlags) -s EXPORT_ES6=1</CMakeConfigurationLinkFlags>
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())
{
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");