[wasm] deprecate legacy JS API and propose new (#73068)

- Added new API methods to top level next to MONO and BINDING namespaces
- marked MONO and BINDING namespaces obsolete
- separated legacy API into dotnet-legacy.d.ts
- renamed snake_case to camelCase names

Co-authored-by: Marek Fišera <mara@neptuo.com>
Co-authored-by: Ankit Jain <radical@gmail.com>
This commit is contained in:
Pavel Savara 2022-08-04 08:19:50 +02:00 committed by GitHub
parent 0ea3031aaf
commit 0d80733c26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 1660 additions and 1385 deletions

1
.gitattributes vendored
View File

@ -76,3 +76,4 @@ src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-
src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input.txt text eol=lf
src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input-big.txt text eol=lf
src/mono/wasm/runtime/dotnet.d.ts text eol=lf
src/mono/wasm/runtime/dotnet-legacy.d.ts text eol=lf

2
.gitignore vendored
View File

@ -188,6 +188,8 @@ node_modules/
*.metaproj.tmp
bin.localpkg/
src/mono/wasm/runtime/dotnet.d.ts.sha256
src/mono/wasm/runtime/dotnet-legacy.d.ts.sha256
src/mono/sample/wasm/browser-nextjs/public/
# RIA/Silverlight projects

View File

@ -181,6 +181,7 @@
$(LibrariesNativeArtifactsPath)dotnet.js;
$(LibrariesNativeArtifactsPath)src\dotnet-crypto-worker.js;
$(LibrariesNativeArtifactsPath)dotnet.d.ts;
$(LibrariesNativeArtifactsPath)dotnet-legacy.d.ts;
$(LibrariesNativeArtifactsPath)package.json;
$(LibrariesNativeArtifactsPath)dotnet.wasm;
$(LibrariesNativeArtifactsPath)dotnet.js.symbols;

View File

@ -218,6 +218,7 @@
<PlatformManifestFileEntry Include="dotnet.worker.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.js.symbols" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.d.ts" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet-legacy.d.ts" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.wasm" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.timezones.blat" IsNative="true" />
<PlatformManifestFileEntry Include="icudt.dat" IsNative="true" />

View File

@ -26,8 +26,8 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
long dummy = 0xA6A6A6A6L;
long actual2 = dummy;
var bagFn = new Function("ptr", "ptr2", @"
const value=globalThis.App.MONO.getI52(ptr);
globalThis.App.MONO.setI52(ptr2, value);
const value=globalThis.App.runtime.getHeapI52(ptr);
globalThis.App.runtime.setHeapI52(ptr2, value);
return ''+value;");
uint ptr = (uint)Unsafe.AsPointer(ref expected);
@ -53,8 +53,8 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
ulong dummy = 0xA6A6A6A6UL;
ulong actual2 = dummy;
var bagFn = new Function("ptr", "ptr2", @"
const value=globalThis.App.MONO.getI52(ptr);
globalThis.App.MONO.setU52(ptr2, value);
const value=globalThis.App.runtime.getHeapI52(ptr);
globalThis.App.runtime.setHeapU52(ptr2, value);
return ''+value;");
uint ptr = (uint)Unsafe.AsPointer(ref expected);
@ -99,14 +99,14 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
long actual = 0;
uint ptr = (uint)Unsafe.AsPointer(ref actual);
var bagFn = new Function("ptr", "value", @"
globalThis.App.MONO.setI52(ptr, value);");
globalThis.App.runtime.setHeapI52(ptr, value);");
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
Assert.Contains("Value is not a safe integer", ex.Message);
double expectedD = value;
uint ptrD = (uint)Unsafe.AsPointer(ref expectedD);
var bagFnD = new Function("ptr", "value", @"
globalThis.App.MONO.getI52(ptr);");
globalThis.App.runtime.getHeapI52(ptr);");
var exD = Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
Assert.Contains("Value is not a safe integer", ex.Message);
}
@ -118,14 +118,14 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
long actual = 0;
uint ptr = (uint)Unsafe.AsPointer(ref actual);
var bagFn = new Function("ptr", "value", @"
globalThis.App.MONO.setU52(ptr, value);");
globalThis.App.runtime.setHeapU52(ptr, value);");
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
Assert.Contains("Can't convert negative Number into UInt64", ex.Message);
double expectedD = value;
uint ptrD = (uint)Unsafe.AsPointer(ref expectedD);
var bagFnD = new Function("ptr", "value", @"
globalThis.App.MONO.getU52(ptr);");
globalThis.App.runtime.getHeapU52(ptr);");
var exD = Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
Assert.Contains("Can't convert negative Number into UInt64", ex.Message);
}
@ -136,7 +136,7 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
long actual = 0;
uint ptr = (uint)Unsafe.AsPointer(ref actual);
var bagFn = new Function("ptr", "value", @"
globalThis.App.MONO.setI52(ptr, value);");
globalThis.App.runtime.setHeapI52(ptr, value);");
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, double.NaN));
Assert.Contains("Value is not a safe integer: NaN (number)", ex.Message);
}

View File

@ -117,7 +117,7 @@ namespace System.Runtime.InteropServices.JavaScript
{
}
// Called by the AOT profiler to save profile data into INTERNAL.aot_profile_data
// Called by the AOT profiler to save profile data into INTERNAL.aotProfileData
[MethodImpl(MethodImplOptions.NoInlining)] // https://github.com/dotnet/runtime/issues/71425
public static unsafe void DumpAotProfileData(ref byte buf, int len, string extraArg)
{
@ -133,7 +133,7 @@ namespace System.Runtime.InteropServices.JavaScript
if (module == null)
throw new InvalidOperationException();
module.SetProperty("aot_profile_data", span.ToArray());
module.SetProperty("aotProfileData", span.ToArray());
}
}
}

View File

@ -20,8 +20,6 @@ namespace System.Runtime.InteropServices.JavaScript
/// public static partial int librarySum(int a, int b);
/// [JSImport("Math.sum", "my-math-helper")]
/// public static partial int libraryNamespaceSum(int a, int b);
/// [JSImport("IMPORTS.sum")]
/// public static partial int runtimeImportsSum(int a, int b);
/// [JSImport("globalThis.Math.sum")]
/// public static partial int globalSum(int a, int b);
/// </code>
@ -31,7 +29,7 @@ namespace System.Runtime.InteropServices.JavaScript
public sealed class JSImportAttribute : Attribute
{
/// <summary>
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the IMPORTS JavaScript object owned by the runtime.
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the module.
/// Functions nested inside of objects can be referred to by using the dot operator to connect one or more names.
/// </summary>
public string FunctionName { get; }
@ -44,7 +42,7 @@ namespace System.Runtime.InteropServices.JavaScript
/// <summary>
/// Initializes a new instance of the <see cref="JSImportAttribute"/>.
/// </summary>
/// <param name="functionName">Name of the function to be bound in the IMPORTS object of the runtime instance in the JavaScript page. It allows dots for nested objects.</param>
/// <param name="functionName">Name of the function to be bound in the module. It allows dots for nested objects.</param>
public JSImportAttribute(string functionName)
{
FunctionName = functionName;
@ -54,7 +52,7 @@ namespace System.Runtime.InteropServices.JavaScript
/// Initializes a new instance of the <see cref="JSImportAttribute"/>.
/// </summary>
/// <param name="functionName">
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the IMPORTS JavaScript object owned by the runtime.
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the module.
/// Functions nested inside of objects can be referred to by using the dot operator to connect one or more names.
/// </param>
/// <param name="moduleName">

View File

@ -918,6 +918,9 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
}
#endregion JSObject
[JSImport("setup", "JavaScriptTestHelper")]
internal static partial Task Setup();
static JSObject _module;
public static async Task InitializeAsync()
{
@ -925,6 +928,7 @@ namespace System.Runtime.InteropServices.JavaScript.Tests
{
// Log("JavaScriptTestHelper.mjs importing");
_module = await JSHost.ImportAsync("JavaScriptTestHelper", "./JavaScriptTestHelper.mjs");
await Setup();
// Log("JavaScriptTestHelper.mjs imported");
}
}

View File

@ -5,8 +5,8 @@ class JSData {
constructor(name) {
this.name = name;
}
echoMemberMethod(arg1){
return arg1 + "-w-i-t-h-"+ this.name;
echoMemberMethod(arg1) {
return arg1 + "-w-i-t-h-" + this.name;
}
toString() {
return `JSData("${this.name}")`;
@ -146,14 +146,14 @@ export function getClass1() {
// console.log(`getClass1(arg1:${cname !== null ? cname : '<null>'})`)
return cname;
}
let dllExports;
export function invoke1(arg1, name) {
if (globalThis.gc) {
// console.log('globalThis.gc');
globalThis.gc();
}
// console.log(`invoke1: ${name}(arg1:${arg1 !== null ? typeof arg1 : '<null>'})`)
const JavaScriptTestHelper = globalThis.App.EXPORTS.System.Runtime.InteropServices.JavaScript.Tests.JavaScriptTestHelper
const JavaScriptTestHelper = dllExports.System.Runtime.InteropServices.JavaScript.Tests.JavaScriptTestHelper;
const fn = JavaScriptTestHelper[name];
// console.log("invoke1:" + typeof fn);
@ -164,8 +164,7 @@ export function invoke1(arg1, name) {
}
export function invoke2(arg1, name) {
const JavaScriptTestHelperNoNamespace = globalThis.App.EXPORTS.JavaScriptTestHelperNoNamespace
const fn = JavaScriptTestHelperNoNamespace[name];
const fn = dllExports.JavaScriptTestHelperNoNamespace[name];
//console.log("invoke1:" + fn.toString());
const res = fn(arg1);
// console.log(`invoke1: res ${res !== null ? typeof res : '<null>'}`)
@ -272,5 +271,8 @@ globalThis.rebound = {
echoMemberMethod: globalThis.data.echoMemberMethod.bind(globalThis.data)
}
export async function setup() {
dllExports = await App.runtime.getAssemblyExports("System.Runtime.InteropServices.JavaScript.Tests.dll");
}
// console.log('JavaScriptTestHelper:' Object.keys(globalThis.JavaScriptTestHelper));

View File

@ -3,8 +3,8 @@ import createDotnetRuntime from './dotnet.js'
try {
const { BINDING } = await createDotnetRuntime(({ MONO }) => ({
configSrc: "./mono-config.json",
onConfigLoaded: () => {
MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
onConfigLoaded: (config) => {
config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
},
}));
const update = BINDING.bind_static_method("[WasmDelta] Sample.Test:Update");

View File

@ -6,28 +6,31 @@
import createDotnetRuntime from './dotnet.js'
class FrameApp {
async init({ MONO }) {
const exports = await MONO.mono_wasm_get_assembly_exports("Wasm.Browser.Bench.Sample.dll");
async init({ getAssemblyExports }) {
const exports = await getAssemblyExports("Wasm.Browser.Bench.Sample.dll");
exports.Sample.AppStartTask.FrameApp.ReachedManaged();
}
reachedCallback() {
if (window.parent != window) {
window.parent.resolveAppStartEvent("reached");
}
}
}
let mute = false;
try {
globalThis.frameApp = new FrameApp();
globalThis.frameApp.ReachedCallback = globalThis.frameApp.reachedCallback.bind(globalThis.frameApp);
let mute = false;
if (window.parent != window) {
window.addEventListener("pageshow", event => { window.parent.resolveAppStartEvent("pageshow"); })
}
window.muteErrors = () => {
mute = true;
}
const { MONO } = await createDotnetRuntime(() => ({
const runtime = await createDotnetRuntime(() => ({
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
printErr: function () {
@ -36,16 +39,20 @@ try {
}
},
onConfigLoaded: () => {
if (window.parent != window) {
window.parent.resolveAppStartEvent("onConfigLoaded");
// Module.config.diagnostic_tracing = true;
}
// Module.config.diagnosticTracing = true;
},
onAbort: (error) => {
wasm_exit(1, error);
},
}));
if (window.parent != window) {
window.parent.resolveAppStartEvent("onDotnetReady");
await frameApp.init({ MONO });
}
await frameApp.init(runtime);
}
catch (err) {
if (!mute) {

View File

@ -10,8 +10,8 @@ let setTasks;
let getFullJsonResults;
class MainApp {
async init({ MONO }) {
const exports = await MONO.mono_wasm_get_assembly_exports("Wasm.Browser.Bench.Sample.dll");
async init({ getAssemblyExports }) {
const exports = await getAssemblyExports("Wasm.Browser.Bench.Sample.dll");
runBenchmark = exports.Sample.Test.RunBenchmark;
setTasks = exports.Sample.Test.SetTasks;
getFullJsonResults = exports.Sample.Test.GetFullJsonResults;
@ -94,14 +94,14 @@ try {
globalThis.mainApp.FrameReachedManaged = globalThis.mainApp.frameReachedManaged.bind(globalThis.mainApp);
globalThis.mainApp.PageShow = globalThis.mainApp.pageShow.bind(globalThis.mainApp);
const { MONO } = await createDotnetRuntime(() => ({
const runtime = await createDotnetRuntime(() => ({
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
onAbort: (error) => {
wasm_exit(1, error);
}
}));
await mainApp.init({ MONO });
await mainApp.init(runtime);
}
catch (err) {
wasm_exit(1, err);

View File

@ -20,23 +20,23 @@
<ItemGroup>
<WasmExtraFilesToDeploy Include="index.html" />
<WasmExtraFilesToDeploy Include="mock.js" Condition="'$(MonoDiagnosticsMock)' == 'true'"/>
<WasmExtraConfig Condition="true" Include="environment_variables" Value='
<WasmExtraConfig Condition="true" Include="environmentVariables" Value='
{
"MONO_LOG_LEVEL": "warning",
"MONO_LOG_MASK": "all"
}' />
<!-- this option requires running dotnet-dsrouter and a real dotnet-trace client -->
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' != 'true'" Include="diagnostic_options" Value='
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' != 'true'" Include="diagnosticOptions" Value='
{
"server": { "suspend": true, "connect_url": "ws://localhost:8088/diagnostics" }
"server": { "suspend": true, "connectUrl": "ws://localhost:8088/diagnostics" }
}' />
<!-- this option requires compiling the runtime with /p:MonoDiagnosticsMock=true and also building this project with the same property-->
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' == 'true'" Include="diagnostic_options" Value='
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' == 'true'" Include="diagnosticOptions" Value='
{
"server": { "suspend": false, "connect_url": "mock:./mock.js" }
"server": { "suspend": false, "connectUrl": "mock:./mock.js" }
}' />
<!-- this option will create an EventPipe session at startup, that will dump its data into the Emscripten VFS -->
<WasmExtraConfig Condition="false" Include="diagnostic_options" Value='
<WasmExtraConfig Condition="false" Include="diagnosticOptions" Value='
{
"sessions": [ { "collectRundownEvents": "true", "providers": "WasmHello::5:EventCounterIntervalSec=1" } ]
}' />

View File

@ -13,7 +13,7 @@
<ItemGroup>
<WasmExtraFilesToDeploy Include="index.html" />
<WasmExtraConfig Include="environment_variables" Value='
<WasmExtraConfig Include="environmentVariables" Value='
{
"DOTNET_EnableEventPipe": "1",
"DOTNET_EventPipeOutputPath": "/trace.nettrace"

View File

@ -22,7 +22,7 @@ function Uint8ToString(u8a) {
}
async function main() {
const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => {
const { MONO, BINDING, Module, runtimeBuildInfo } = await createDotnetRuntime(() => {
console.log('user code in createDotnetRuntime')
return {
disableDotnet6Compatibility: true,
@ -40,7 +40,7 @@ async function main() {
try {
const testMeaning = BINDING.bind_static_method("[Wasm.Browser.ThreadsEP.Sample] Sample.Test:TestMeaning");
const ret = testMeaning();
document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`;
document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${runtimeBuildInfo.productVersion}`;
console.debug(`ret: ${ret}`);

View File

@ -14,8 +14,8 @@
```
await createDotnetRuntime(() => ({
onConfigLoaded: () => {
if (config.enable_profiler) {
config.aot_profiler_options = {
if (config.enableProfiler) {
config.aotProfilerOptions = {
write_at: "<Namespace.Class::StopProfile>",
send_to: "System.Runtime.InteropServices.JavaScript.JavaScriptExports::DumpAotProfileData"
}
@ -28,14 +28,14 @@ await createDotnetRuntime(() => ({
`BINDING.bind_static_method("<[ProjectName] Namespace.Class::StopProfile">)();`
When the `write_at` method is called, the `send_to` method `DumpAotProfileData` stores the profile data into `INTERNAL.aot_profile_data`
When the `write_at` method is called, the `send_to` method `DumpAotProfileData` stores the profile data into `INTERNAL.aotProfileData`
4. Download `INTERNAL.aot_profile_data` in JS, using something similar to:
4. Download `INTERNAL.aotProfileData` in JS, using something similar to:
```
function saveProfile() {
var a = document.createElement('a');
var blob = new Blob([INTERNAL.aot_profile_data]);
var blob = new Blob([INTERNAL.aotProfileData]);
a.href = URL.createObjectURL(blob);
a.download = "data.aotprofile";
// Append anchor to body.

View File

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<WasmExtraConfig Include="enable_profiler" Value="true" />
<WasmExtraConfig Include="enableProfiler" Value="true" />
<WasmExtraFilesToDeploy Include="index.html" />
</ItemGroup>

View File

@ -12,12 +12,12 @@ function wasm_exit(exit_code, reason) {
console.log(`WASM EXIT ${exit_code}`);
}
function saveProfile(aot_profile_data) {
if (!aot_profile_data) {
throw new Error("aot_profile_data not set")
function saveProfile(aotProfileData) {
if (!aotProfileData) {
throw new Error("aotProfileData not set")
}
const a = document.createElement('a');
const blob = new Blob([aot_profile_data]);
const blob = new Blob([aotProfileData]);
a.href = URL.createObjectURL(blob);
a.download = "data.aotprofile";
// Append anchor to body.
@ -32,11 +32,11 @@ try {
const { MONO, BINDING, INTERNAL } = await createDotnetRuntime(({ MONO }) => ({
configSrc: "./mono-config.json",
disableDotnet6Compatibility: true,
onConfigLoaded: () => {
if (MONO.config.enable_profiler) {
MONO.config.aot_profiler_options = {
write_at: "Sample.Test::StopProfile",
send_to: "System.Runtime.InteropServices.JavaScript.JavaScriptExports::DumpAotProfileData"
onConfigLoaded: (config) => {
if (config.enableProfiler) {
config.aotProfilerOptions = {
writeAt: "Sample.Test::StopProfile",
sendTo: "System.Runtime.InteropServices.JavaScript.JavaScriptExports::DumpAotProfileData"
}
}
},
@ -49,9 +49,9 @@ try {
document.getElementById("out").innerHTML = ret;
console.debug(`ret: ${ret}`);
if (MONO.config.enable_profiler) {
if (MONO.config.enableProfiler) {
stopProfile();
saveProfile(INTERNAL.aot_profile_data);
saveProfile(INTERNAL.aotProfileData);
}
let exit_code = ret == 42 ? 0 : 1;

View File

@ -12,11 +12,13 @@
<Target Name="CopyRelinkedPackage" AfterTargets="WasmBuildApp" DependsOnTargets="Build" Inputs="$(WasmAppDir)/dotnet.js;
$(WasmAppDir)/dotnet.wasm;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json;" Outputs="bin/dotnet-runtime/.npm-stamp">
<ItemGroup>
<NpmPackageFiles Include="$(WasmAppDir)/dotnet.js"/>
<NpmPackageFiles Include="$(WasmAppDir)/dotnet.wasm"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json"/>
</ItemGroup>
<Copy SourceFiles="@(NpmPackageFiles)" DestinationFolder="bin/dotnet-runtime" />

View File

@ -15,10 +15,10 @@ namespace Sample
return 0;
}
[JSImport("Sample.Test.add")]
[JSImport("Sample.Test.add", "main.js")]
internal static partial int Add(int a, int b);
[JSImport("Sample.Test.sub")]
[JSImport("Sample.Test.sub", "main.js")]
internal static partial int Sub(int a, int b);
[JSExport]

View File

@ -12,6 +12,11 @@ function wasm_exit(exit_code, reason) {
console.log(`WASM EXIT ${exit_code}`);
}
/**
* @type {import('../../../wasm/runtime/dotnet').CreateDotnetRuntimeType}
*/
const createDotnetRuntimeTyped = createDotnetRuntime;
function add(a, b) {
return a + b;
}
@ -19,36 +24,55 @@ function add(a, b) {
function sub(a, b) {
return a - b;
}
try {
const { MONO, RuntimeBuildInfo, IMPORTS } = await createDotnetRuntime(() => {
console.log('user code in createDotnetRuntime callback');
const { runtimeBuildInfo, setModuleImports, getAssemblyExports, runMain } = await createDotnetRuntimeTyped(() => {
// this callback usually needs no statements, the API objects are only empty shells here and are populated later
return {
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
// This is called during emscripten `dotnet.wasm` instantiation, after we fetched config.
console.log('user code Module.onConfigLoaded');
// config is loaded and could be tweaked before the rest of the runtime startup sequence
config.environmentVariables["MONO_LOG_LEVEL"] = "debug"
},
preInit: () => { console.log('user code Module.preInit'); },
preRun: () => { console.log('user code Module.preRun'); },
onRuntimeInitialized: () => { console.log('user code Module.onRuntimeInitialized'); },
onRuntimeInitialized: () => {
console.log('user code Module.onRuntimeInitialized');
// here we could use API passed into this callback
// Module.FS.chdir("/");
},
onDotnetReady: () => {
// This is called after all assets are loaded.
console.log('user code Module.onDotnetReady');
},
postRun: () => { console.log('user code Module.postRun'); },
}
});
// at this point both emscripten and monoVM are fully initialized.
// we could use the APIs returned and resolved from createDotnetRuntime promise
// both exports are receiving the same object instances
console.log('user code after createDotnetRuntime()');
IMPORTS.Sample = {
setModuleImports("main.js", {
Sample: {
Test: {
add,
sub
}
};
}
});
const exports = await MONO.mono_wasm_get_assembly_exports("Wasm.Browser.Sample.dll");
const exports = await getAssemblyExports("Wasm.Browser.Sample.dll");
const meaning = exports.Sample.Test.TestMeaning();
console.debug(`meaning: ${meaning}`);
if (!exports.Sample.Test.IsPrime(meaning)) {
document.getElementById("out").innerHTML = `${meaning} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`;
document.getElementById("out").innerHTML = `${meaning} as computed on dotnet ver ${runtimeBuildInfo.productVersion}`;
console.debug(`ret: ${meaning}`);
}
let exit_code = await MONO.mono_run_main("Wasm.Browser.Sample.dll", []);
let exit_code = await runMain("Wasm.Browser.Sample.dll", []);
wasm_exit(exit_code);
} catch (err) {
}
catch (err) {
wasm_exit(2, err);
}

View File

@ -1,10 +1,18 @@
// @ts-check
// @ts-ignore
import createDotnetRuntime from './dotnet.js'
import process from 'process'
const { MONO } = await createDotnetRuntime(() => ({
/**
* @type {import('../../../wasm/runtime/dotnet').CreateDotnetRuntimeType}
*/
const createDotnetRuntimeTyped = createDotnetRuntime;
const { runMainAndExit } = await createDotnetRuntimeTyped(() => ({
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
}));
const app_args = process.argv.slice(2);
const dllName = "Wasm.Console.Node.Sample.dll";
await MONO.mono_run_main_and_exit(dllName, app_args);
await runMainAndExit(dllName, app_args);

View File

@ -10,9 +10,11 @@
-->
<Target Name="CopyRelinkedPackage" AfterTargets="WasmBuildApp" DependsOnTargets="Build" Inputs="
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json;" Outputs="bin/$(Configuration)/AppBundle/.npm-stamp">
<ItemGroup>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json"/>
</ItemGroup>
<Copy SourceFiles="@(NpmPackageFiles)" DestinationFolder="bin/$(Configuration)/AppBundle" SkipUnchangedFiles="true"/>

View File

@ -4,8 +4,8 @@ const dllName = "Wasm.Console.V8.Sample.dll";
const app_args = Array.from(arguments);
async function main() {
const { MONO } = await createDotnetRuntime();
await MONO.mono_run_main_and_exit(dllName, app_args);
const { runMainAndExit } = await createDotnetRuntime();
await runMainAndExit(dllName, app_args);
}
main();

View File

@ -1,14 +1,3 @@
if (typeof globalThis.URL === 'undefined') {
globalThis.URL = class URL {
constructor(url) {
this.url = url;
}
toString() {
return this.url;
}
};
}
import('./main.mjs').catch(err => {
console.log(err);
console.log(err.stack);

View File

@ -7,11 +7,13 @@
<Target Name="CopyRelinkedPackage" AfterTargets="WasmBuildApp" DependsOnTargets="Build" Inputs="$(WasmAppDir)/dotnet.js;
$(WasmAppDir)/dotnet.wasm;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts;
$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json;" Outputs="bin/dotnet-runtime/.npm-stamp">
<ItemGroup>
<NpmPackageFiles Include="$(WasmAppDir)/dotnet.js"/>
<NpmPackageFiles Include="$(WasmAppDir)/dotnet.wasm"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts"/>
<NpmPackageFiles Include="$(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json"/>
</ItemGroup>
<Copy SourceFiles="@(NpmPackageFiles)" DestinationFolder="bin/dotnet-runtime" />

View File

@ -17,7 +17,7 @@
- $(RunAOTCompilation) - Defaults to false.
- $(WasmDebugLevel)
> 0 enables debugging and sets the debug log level to debug_level
> 0 enables debugging and sets the debug log level to debugLevel
== 0 disables debugging and enables interpreter optimizations
< 0 enabled debugging and disables debug logging.
@ -75,7 +75,7 @@
- @(WasmNativeAsset) - Native files to be added to `NativeAssets` in the bundle.
- @(WasmExtraConfig) - json elements to add to `mono-config.json`
Eg. <WasmExtraConfig Include="enable_profiler" Value="true" />
Eg. <WasmExtraConfig Include="enableProfiler" Value="true" />
- Value attribute can have a number, bool, quoted string, or json string

View File

@ -7,14 +7,14 @@
var App = {
static_method_table: {},
init: function () {
this.int_add = App.BINDING.bind_static_method("[debugger-test] Math:IntAdd");
this.use_complex = App.BINDING.bind_static_method("[debugger-test] Math:UseComplex");
this.delegates_test = App.BINDING.bind_static_method("[debugger-test] Math:DelegatesTest");
this.generic_types_test = App.BINDING.bind_static_method("[debugger-test] Math:GenericTypesTest");
this.outer_method = App.BINDING.bind_static_method("[debugger-test] Math:OuterMethod");
this.async_method = App.BINDING.bind_static_method("[debugger-test] Math/NestedInMath:AsyncTest");
this.method_with_structs = App.BINDING.bind_static_method("[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalStructs");
this.run_all = App.BINDING.bind_static_method("[debugger-test] DebuggerTest:run_all");
this.int_add = App.runtime.BINDING.bind_static_method("[debugger-test] Math:IntAdd");
this.use_complex = App.runtime.BINDING.bind_static_method("[debugger-test] Math:UseComplex");
this.delegates_test = App.runtime.BINDING.bind_static_method("[debugger-test] Math:DelegatesTest");
this.generic_types_test = App.runtime.BINDING.bind_static_method("[debugger-test] Math:GenericTypesTest");
this.outer_method = App.runtime.BINDING.bind_static_method("[debugger-test] Math:OuterMethod");
this.async_method = App.runtime.BINDING.bind_static_method("[debugger-test] Math/NestedInMath:AsyncTest");
this.method_with_structs = App.runtime.BINDING.bind_static_method("[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalStructs");
this.run_all = App.runtime.BINDING.bind_static_method("[debugger-test] DebuggerTest:run_all");
this.static_method_table = {};
console.log ("ready");
},
@ -22,7 +22,7 @@
function invoke_static_method (method_name, ...args) {
var method = App.static_method_table [method_name];
if (method == undefined)
method = App.static_method_table[method_name] = App.BINDING.bind_static_method(method_name);
method = App.static_method_table[method_name] = App.runtime.BINDING.bind_static_method(method_name);
return method (...args);
}
@ -30,7 +30,7 @@
async function invoke_static_method_async (method_name, ...args) {
var method = App.static_method_table [method_name];
if (method == undefined) {
method = App.static_method_table[method_name] = App.BINDING.bind_static_method(method_name);
method = App.static_method_table[method_name] = App.runtime.BINDING.bind_static_method(method_name);
}
return await method (...args);

View File

@ -6,14 +6,14 @@
import createDotnetRuntime from './dotnet.js'
try {
const { BINDING } = await createDotnetRuntime(({ INTERNAL }) => ({
const runtime = await createDotnetRuntime(({ INTERNAL }) => ({
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
/* For custom logging patch the functions below
config.diagnostic_tracing = true;
config.environment_variables["MONO_LOG_LEVEL"] = "debug";
config.environment_variables["MONO_LOG_MASK"] = "all";
config.diagnosticTracing = true;
config.environmentVariables["MONO_LOG_LEVEL"] = "debug";
config.environmentVariables["MONO_LOG_MASK"] = "all";
INTERNAL.logging = {
trace: (domain, log_level, message, isFatal, dataPtr) => console.log({ domain, log_level, message, isFatal, dataPtr }),
debugger: (level, message) => console.log({ level, message }),
@ -21,7 +21,7 @@ try {
*/
},
}));
App.BINDING = BINDING;
App.runtime = runtime;
App.init()
} catch (err) {
console.log(`WASM ERROR ${err}`);

View File

@ -1,15 +1,15 @@
<!doctype html>
<html lang="en-us">
<head>
</head>
<body>
<head>
</head>
<body>
<script type='text/javascript'>
var App = {
init: function () {
MONO.loaded_files = null;
},
init: function () { },
};
function reload_wasm_page () {
function reload_wasm_page() {
window.location.replace("http://localhost:9400/debugger-driver.html");
}
</script>
@ -17,5 +17,6 @@
<script type="text/javascript" src="other.js"></script>
Stuff goes here
</body>
</body>
</html>

View File

@ -1,117 +0,0 @@
// 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";
#if USE_PTHREADS
const usePThreads = `true`;
const isPThread = `ENVIRONMENT_IS_PTHREAD`;
#else
const usePThreads = `false`;
const isPThread = `false`;
#endif
const DotnetSupportLib = {
$DOTNET: {},
// these lines will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE
// we replace implementation of fetch
// replacement of require is there for consistency with ES6 code
$DOTNET__postset: `
let __dotnet_replacement_PThread = ${usePThreads} ? {} : undefined;
if (${usePThreads}) {
__dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker;
__dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS;
}
let __dotnet_replacements = {scriptUrl: undefined, fetch: globalThis.fetch, require, updateGlobalBufferAndViews, pthreadReplacements: __dotnet_replacement_PThread};
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise = Promise.resolve(require);
}
let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports(
{ isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, quit_, ExitStatus, requirePromise:Promise.resolve(require)},
{ mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_exports: EXPORTS, marshaled_imports: IMPORTS },
__dotnet_replacements);
updateGlobalBufferAndViews = __dotnet_replacements.updateGlobalBufferAndViews;
var fetch = __dotnet_replacements.fetch;
_scriptDir = __dirname = scriptDirectory = __dotnet_replacements.scriptDirectory;
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise.then(someRequire => {
require = someRequire;
});
}
var noExitRuntime = __dotnet_replacements.noExitRuntime;
if (${usePThreads}) {
PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker;
PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTS;
}
`,
};
// the methods would be visible to EMCC linker
// --- keep in sync with exports.ts ---
const linked_functions = [
// mini-wasm.c
"mono_set_timeout",
// mini-wasm-debugger.c
"mono_wasm_asm_loaded",
"mono_wasm_fire_debugger_agent_message",
"mono_wasm_debugger_log",
"mono_wasm_add_dbg_command_received",
// mono-threads-wasm.c
"schedule_background_exec",
// driver.c
"mono_wasm_invoke_js_blazor",
"mono_wasm_trace_logger",
"mono_wasm_set_entrypoint_breakpoint",
"mono_wasm_event_pipe_early_startup_callback",
// corebindings.c
"mono_wasm_invoke_js_with_args_ref",
"mono_wasm_get_object_property_ref",
"mono_wasm_set_object_property_ref",
"mono_wasm_get_by_index_ref",
"mono_wasm_set_by_index_ref",
"mono_wasm_get_global_object_ref",
"mono_wasm_create_cs_owned_object_ref",
"mono_wasm_release_cs_owned_object",
"mono_wasm_typed_array_to_array_ref",
"mono_wasm_typed_array_from_ref",
"mono_wasm_compile_function_ref",
"mono_wasm_bind_js_function",
"mono_wasm_invoke_bound_function",
"mono_wasm_bind_cs_function",
"mono_wasm_marshal_promise",
// pal_icushim_static.c
"mono_wasm_load_icu_data",
"mono_wasm_get_icudt_name",
// pal_crypto_webworker.c
"dotnet_browser_can_use_subtle_crypto_impl",
"dotnet_browser_simple_digest_hash",
"dotnet_browser_sign",
"dotnet_browser_encrypt_decrypt",
"dotnet_browser_derive_bits",
#if USE_PTHREADS
/// mono-threads-wasm.c
"mono_wasm_pthread_on_pthread_attached",
/// diagnostics_server.c
"mono_wasm_diagnostic_server_on_server_thread_created",
"mono_wasm_diagnostic_server_on_runtime_server_init",
"mono_wasm_diagnostic_server_stream_signal_work_available",
#endif
];
// -- 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.__linker_exports.${linked_function}.apply(__dotnet_runtime, arguments)`;
DotnetSupportLib[linked_function] = new Function(fn_template);
}
autoAddDeps(DotnetSupportLib, "$DOTNET");
mergeInto(LibraryManager.library, DotnetSupportLib);

View File

@ -4,10 +4,9 @@
import {
MonoArray, MonoAssembly, MonoClass,
MonoMethod, MonoObject, MonoString,
MonoType, MonoObjectRef, MonoStringRef
MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments
} from "./types";
import { ENVIRONMENT_IS_PTHREAD, Module } from "./imports";
import { JSMarshalerArguments } from "./marshal";
import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten";
type SigLine = [lazy: boolean, name: string, returnType: string | null, argTypes?: string[], opts?: any];
@ -112,7 +111,7 @@ export interface t_Cwraps {
mono_wasm_get_icudt_name(name: string): string;
mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number;
mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void;
mono_wasm_load_runtime(unused: string, debug_level: number): void;
mono_wasm_load_runtime(unused: string, debugLevel: number): void;
mono_wasm_change_debugger_log_level(value: number): void;
/**

View File

@ -150,7 +150,7 @@ export function mono_wasm_get_loaded_files(): string[] {
export function mono_wasm_wait_for_debugger(): Promise<void> {
return new Promise<void>((resolve) => {
const interval = setInterval(() => {
if (runtimeHelpers.wait_for_debugger != 1) {
if (runtimeHelpers.waitForDebugger != 1) {
return;
}
clearInterval(interval);
@ -160,8 +160,8 @@ export function mono_wasm_wait_for_debugger(): Promise<void> {
}
export function mono_wasm_debugger_attached(): void {
if (runtimeHelpers.wait_for_debugger == -1)
runtimeHelpers.wait_for_debugger = 1;
if (runtimeHelpers.waitForDebugger == -1)
runtimeHelpers.waitForDebugger = 1;
cwraps.mono_wasm_set_is_debugger_attached(true);
}

View File

@ -27,9 +27,9 @@ To use mocking:
3. configure the diagnostics server with a `mock:relative_url_of/mock.js`
```xml
<WasmExtraConfig Include="diagnostic_options" Value='
<WasmExtraConfig Include="diagnosticOptions" Value='
{
"server": { "suspend": false, "connect_url": "mock:./mock.js" }
"server": { "suspend": false, "connectUrl": "mock:./mock.js" }
}' />
```

View File

@ -15,7 +15,7 @@ export const eventLevel = {
export type EventLevel = typeof eventLevel;
type UnnamedProviderConfiguration = Partial<{
keyword_mask: string | 0;
keywordMask: string | 0;
level: number;
args: string;
}>
@ -40,19 +40,19 @@ const sampleProfilerProviderName = "Microsoft-DotNETCore-SampleProfiler";
const runtimeProviderDefault: ProviderConfiguration = {
name: runtimeProviderName,
keyword_mask: "4c14fccbd",
keywordMask: "4c14fccbd",
level: eventLevel.Verbose,
};
const runtimePrivateProviderDefault: ProviderConfiguration = {
name: runtimePrivateProviderName,
keyword_mask: "4002000b",
keywordMask: "4002000b",
level: eventLevel.Verbose,
};
const sampleProfilerProviderDefault: ProviderConfiguration = {
name: sampleProfilerProviderName,
keyword_mask: "0",
keywordMask: "0",
level: eventLevel.Verbose,
};
@ -83,21 +83,21 @@ export class SessionOptionsBuilder {
return this;
}
/// Add the Microsoft-Windows-DotNETRuntime provider. Use override options to change the event level or keyword mask.
/// The default is { keyword_mask: "4c14fccbd", level: eventLevel.Verbose }
/// The default is { keywordMask: "4c14fccbd", level: eventLevel.Verbose }
addRuntimeProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder {
const options = { ...runtimeProviderDefault, ...overrideOptions };
this._providers.push(options);
return this;
}
/// Add the Microsoft-Windows-DotNETRuntimePrivate provider. Use override options to change the event level or keyword mask.
/// The default is { keyword_mask: "4002000b", level: eventLevel.Verbose}
/// The default is { keywordMask: "4002000b", level: eventLevel.Verbose}
addRuntimePrivateProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder {
const options = { ...runtimePrivateProviderDefault, ...overrideOptions };
this._providers.push(options);
return this;
}
/// Add the Microsoft-DotNETCore-SampleProfiler. Use override options to change the event level or keyword mask.
// The default is { keyword_mask: 0, level: eventLevel.Verbose }
// The default is { keywordMask: 0, level: eventLevel.Verbose }
addSampleProfilerProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder {
const options = { ...sampleProfilerProviderDefault, ...overrideOptions };
this._providers.push(options);
@ -107,11 +107,11 @@ export class SessionOptionsBuilder {
build(): EventPipeSessionOptions {
const providers = this._providers.map(p => {
const name = p.name;
const keyword_mask = "" + (p?.keyword_mask ?? "");
const keywordMask = "" + (p?.keywordMask ?? "");
const level = p?.level ?? eventLevel.Verbose;
const args = p?.args ?? "";
const maybeArgs = args != "" ? `:${args}` : "";
return `${name}:${keyword_mask}:${level}${maybeArgs}`;
return `${name}:${keywordMask}:${level}${maybeArgs}`;
});
return {
collectRundownEvents: this._rundown,

View File

@ -19,7 +19,7 @@ import {
import { EventPipeSession, makeEventPipeSession } from "./browser/file-session";
export interface Diagnostics {
EventLevel: EventLevel;
eventLevel: EventLevel;
SessionOptionsBuilder: typeof SessionOptionsBuilder;
createEventPipeSession(options?: EventPipeSessionOptions): EventPipeSession | null;
@ -62,7 +62,7 @@ function getDiagnostics(): Diagnostics {
/// Warning: 3,
/// Informational: 4,
/// Verbose: 5,
EventLevel: eventLevel,
eventLevel: eventLevel,
/// A builder for creating an EventPipeSessionOptions instance.
SessionOptionsBuilder: SessionOptionsBuilder,
/// Creates a new EventPipe session that will collect trace events from the runtime and managed libraries.
@ -100,10 +100,10 @@ export async function mono_wasm_init_diagnostics(options: DiagnosticOptions): Pr
return;
} else {
if (!is_nullish(options.server)) {
if (options.server.connect_url === undefined || typeof (options.server.connect_url) !== "string") {
throw new Error("server.connect_url must be a string");
if (options.server.connectUrl === undefined || typeof (options.server.connectUrl) !== "string") {
throw new Error("server.connectUrl must be a string");
}
const url = options.server.connect_url;
const url = options.server.connectUrl;
const suspend = boolsyOption(options.server.suspend);
const controller = await startDiagnosticServer(url);
if (controller) {

439
src/mono/wasm/runtime/dotnet-legacy.d.ts vendored Normal file
View File

@ -0,0 +1,439 @@
//! Licensed to the .NET Foundation under one or more agreements.
//! The .NET Foundation licenses this file to you under the MIT license.
//!
//! This is generated file, see src/mono/wasm/runtime/rollup.config.js
//! This is not considered public API with backward compatibility guarantees.
declare interface ManagedPointer {
__brandManagedPointer: "ManagedPointer";
}
declare interface NativePointer {
__brandNativePointer: "NativePointer";
}
declare interface VoidPtr extends NativePointer {
__brand: "VoidPtr";
}
declare function mono_wasm_runtime_ready(): void;
declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean;
interface MonoObject extends ManagedPointer {
__brandMonoObject: "MonoObject";
}
interface MonoString extends MonoObject {
__brand: "MonoString";
}
interface MonoArray extends MonoObject {
__brand: "MonoArray";
}
interface MonoObjectRef extends ManagedPointer {
__brandMonoObjectRef: "MonoObjectRef";
}
declare function mono_wasm_get_assembly_exports(assembly: string): Promise<any>;
declare type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
declare type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
declare function setB32(offset: _MemOffset, value: number | boolean): void;
declare function setU8(offset: _MemOffset, value: number): void;
declare function setU16(offset: _MemOffset, value: number): void;
declare function setU32(offset: _MemOffset, value: _NumberOrPointer): void;
declare function setI8(offset: _MemOffset, value: number): void;
declare function setI16(offset: _MemOffset, value: number): void;
declare function setI32(offset: _MemOffset, value: number): void;
/**
* Throws for values which are not 52 bit integer. See Number.isSafeInteger()
*/
declare function setI52(offset: _MemOffset, value: number): void;
/**
* Throws for values which are not 52 bit integer or are negative. See Number.isSafeInteger().
*/
declare function setU52(offset: _MemOffset, value: number): void;
declare function setI64Big(offset: _MemOffset, value: bigint): void;
declare function setF32(offset: _MemOffset, value: number): void;
declare function setF64(offset: _MemOffset, value: number): void;
declare function getB32(offset: _MemOffset): boolean;
declare function getU8(offset: _MemOffset): number;
declare function getU16(offset: _MemOffset): number;
declare function getU32(offset: _MemOffset): number;
declare function getI8(offset: _MemOffset): number;
declare function getI16(offset: _MemOffset): number;
declare function getI32(offset: _MemOffset): number;
/**
* Throws for Number.MIN_SAFE_INTEGER > value > Number.MAX_SAFE_INTEGER
*/
declare function getI52(offset: _MemOffset): number;
/**
* Throws for 0 > value > Number.MAX_SAFE_INTEGER
*/
declare function getU52(offset: _MemOffset): number;
declare function getI64Big(offset: _MemOffset): bigint;
declare function getF32(offset: _MemOffset): number;
declare function getF64(offset: _MemOffset): number;
declare function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr;
/**
* Allocates a block of memory that can safely contain pointers into the managed heap.
* The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers.
* Once you are done using the root buffer, you must call its release() method.
* For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
*/
declare function mono_wasm_new_root_buffer(capacity: number, name?: string): WasmRootBuffer;
/**
* Allocates a WasmRoot pointing to a root provided and controlled by external code. Typicaly on managed stack.
* Releasing this root will not de-allocate the root space. You still need to call .release().
*/
declare function mono_wasm_new_external_root<T extends MonoObject>(address: VoidPtr | MonoObjectRef): WasmRoot<T>;
/**
* Allocates temporary storage for a pointer into the managed heap.
* Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected.
* If you already have a managed pointer you can pass it as an argument to initialize the temporary storage.
* The result object has get() and set(value) methods, along with a .value property.
* When you are done using the root you must call its .release() method.
*/
declare function mono_wasm_new_root<T extends MonoObject>(value?: T | undefined): WasmRoot<T>;
/**
* Releases 1 or more root or root buffer objects.
* Multiple objects may be passed on the argument list.
* 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
* even if you are not sure all of your roots have been created yet.
* @param {... WasmRoot} roots
*/
declare function mono_wasm_release_roots(...args: WasmRoot<any>[]): void;
declare class WasmRootBuffer {
private __count;
private length;
private __offset;
private __offset32;
private __handle;
private __ownsAllocation;
constructor(offset: VoidPtr, capacity: number, ownsAllocation: boolean, name?: string);
_throw_index_out_of_range(): void;
_check_in_range(index: number): void;
get_address(index: number): MonoObjectRef;
get_address_32(index: number): number;
get(index: number): ManagedPointer;
set(index: number, value: ManagedPointer): ManagedPointer;
copy_value_from_address(index: number, sourceAddress: MonoObjectRef): void;
_unsafe_get(index: number): number;
_unsafe_set(index: number, value: ManagedPointer | NativePointer): void;
clear(): void;
release(): void;
toString(): string;
}
interface WasmRoot<T extends MonoObject> {
get_address(): MonoObjectRef;
get_address_32(): number;
get address(): MonoObjectRef;
get(): T;
set(value: T): T;
get value(): T;
set value(value: T);
copy_from_address(source: MonoObjectRef): void;
copy_to_address(destination: MonoObjectRef): void;
copy_from(source: WasmRoot<T>): void;
copy_to(destination: WasmRoot<T>): void;
valueOf(): T;
clear(): void;
release(): void;
toString(): string;
}
declare function mono_run_main_and_exit(main_assembly_name: string, args: string[]): Promise<void>;
declare function mono_run_main(main_assembly_name: string, args: string[]): Promise<number>;
declare function mono_wasm_setenv(name: string, value: string): void;
declare function mono_wasm_load_data_archive(data: Uint8Array, prefix: string): boolean;
/**
* Loads the mono config file (typically called mono-config.json) asynchroniously
* Note: the run dependencies are so emsdk actually awaits it in order.
*
* @param {string} configFilePath - relative path to the config file
* @throws Will throw an error if the config file loading fails
*/
declare function mono_wasm_load_config(configFilePath: string): Promise<void>;
/**
* @deprecated Not GC or thread safe
*/
declare function conv_string(mono_obj: MonoString): string | null;
declare function conv_string_root(root: WasmRoot<MonoString>): string | null;
declare function js_string_to_mono_string_root(string: string, result: WasmRoot<MonoString>): void;
/**
* @deprecated Not GC or thread safe
*/
declare function js_string_to_mono_string(string: string): MonoString;
declare function unbox_mono_obj(mono_obj: MonoObject): any;
declare function unbox_mono_obj_root(root: WasmRoot<any>): any;
declare function mono_array_to_js_array(mono_array: MonoArray): any[] | null;
declare function mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>): any[] | null;
/**
* @deprecated Not GC or thread safe. For blazor use only
*/
declare function js_to_mono_obj(js_obj: any): MonoObject;
declare function js_to_mono_obj_root(js_obj: any, result: WasmRoot<MonoObject>, should_add_in_flight: boolean): void;
declare function js_typed_array_to_array_root(js_obj: any, result: WasmRoot<MonoArray>): void;
/**
* @deprecated Not GC or thread safe
*/
declare function js_typed_array_to_array(js_obj: any): MonoArray;
declare function mono_bind_static_method(fqn: string, signature?: string): Function;
declare function mono_call_assembly_entry_point(assembly: string, args?: any[], signature?: string): number;
/**
* @deprecated Please use methods in top level API object instead
*/
declare type BINDINGType = {
/**
* @deprecated Please use [JSExportAttribute] instead
*/
bind_static_method: typeof mono_bind_static_method;
/**
* @deprecated Please use runMain() instead
*/
call_assembly_entry_point: typeof mono_call_assembly_entry_point;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_new: (size: number) => MonoArray;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void;
/**
* @deprecated Not GC or thread safe
*/
js_string_to_mono_string: typeof js_string_to_mono_string;
/**
* @deprecated Not GC or thread safe
*/
js_typed_array_to_array: typeof js_typed_array_to_array;
/**
* @deprecated Not GC or thread safe
*/
mono_array_to_js_array: typeof mono_array_to_js_array;
/**
* @deprecated Not GC or thread safe
*/
js_to_mono_obj: typeof js_to_mono_obj;
/**
* @deprecated Not GC or thread safe
*/
conv_string: typeof conv_string;
/**
* @deprecated Not GC or thread safe
*/
unbox_mono_obj: typeof unbox_mono_obj;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_to_mono_obj_root: typeof js_to_mono_obj_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
conv_string_root: typeof conv_string_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
unbox_mono_obj_root: typeof unbox_mono_obj_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
};
/**
* @deprecated Please use methods in top level API object instead
*/
declare type MONOType = {
/**
* @deprecated Please use setEnvironmentVariable() instead
*/
mono_wasm_setenv: typeof mono_wasm_setenv;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
/**
* @deprecated Please use configSrc instead
*/
mono_wasm_load_config: typeof mono_wasm_load_config;
/**
* @deprecated Please use runMain instead
*/
mono_load_runtime_and_bcl_args: Function;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_root: typeof mono_wasm_new_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_release_roots: typeof mono_wasm_release_roots;
/**
* @deprecated Please use runMain instead
*/
mono_run_main: typeof mono_run_main;
/**
* @deprecated Please use runMainAndExit instead
*/
mono_run_main_and_exit: typeof mono_run_main_and_exit;
/**
* @deprecated Please use getAssemblyExports instead
*/
mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_runtime: (unused: string, debugLevel: number) => void;
/**
* @deprecated Please use getConfig() instead
*/
config: any;
/**
* @deprecated Please use config.assets instead
*/
loaded_files: string[];
/**
* @deprecated Please use setHeapB32
*/
setB32: typeof setB32;
/**
* @deprecated Please use setHeapI8
*/
setI8: typeof setI8;
/**
* @deprecated Please use setHeapI16
*/
setI16: typeof setI16;
/**
* @deprecated Please use setHeapI32
*/
setI32: typeof setI32;
/**
* @deprecated Please use setHeapI52
*/
setI52: typeof setI52;
/**
* @deprecated Please use setHeapU52
*/
setU52: typeof setU52;
/**
* @deprecated Please use setHeapI64Big
*/
setI64Big: typeof setI64Big;
/**
* @deprecated Please use setHeapU8
*/
setU8: typeof setU8;
/**
* @deprecated Please use setHeapU16
*/
setU16: typeof setU16;
/**
* @deprecated Please use setHeapU32
*/
setU32: typeof setU32;
/**
* @deprecated Please use setHeapF32
*/
setF32: typeof setF32;
/**
* @deprecated Please use setHeapF64
*/
setF64: typeof setF64;
/**
* @deprecated Please use getHeapB32
*/
getB32: typeof getB32;
/**
* @deprecated Please use getHeapI8
*/
getI8: typeof getI8;
/**
* @deprecated Please use getHeapI16
*/
getI16: typeof getI16;
/**
* @deprecated Please use getHeapI32
*/
getI32: typeof getI32;
/**
* @deprecated Please use getHeapI52
*/
getI52: typeof getI52;
/**
* @deprecated Please use getHeapU52
*/
getU52: typeof getU52;
/**
* @deprecated Please use getHeapI64Big
*/
getI64Big: typeof getI64Big;
/**
* @deprecated Please use getHeapU8
*/
getU8: typeof getU8;
/**
* @deprecated Please use getHeapU16
*/
getU16: typeof getU16;
/**
* @deprecated Please use getHeapU32
*/
getU32: typeof getU32;
/**
* @deprecated Please use getHeapF32
*/
getF32: typeof getF32;
/**
* @deprecated Please use getHeapF64
*/
getF64: typeof getF64;
};
export { BINDINGType, MONOType };

View File

@ -5,9 +5,6 @@
//! This is not considered public API with backward compatibility guarantees.
declare interface ManagedPointer {
__brandManagedPointer: "ManagedPointer";
}
declare interface NativePointer {
__brandNativePointer: "NativePointer";
}
@ -51,101 +48,134 @@ declare interface EmscriptenModule {
stackAlloc(size: number): VoidPtr;
ready: Promise<unknown>;
instantiateWasm?: (imports: WebAssembly.Imports, successCallback: (instance: WebAssembly.Instance, module: WebAssembly.Module) => void) => any;
preInit?: (() => any)[];
preRun?: (() => any)[];
preInit?: (() => any)[] | (() => any);
preRun?: (() => any)[] | (() => any);
onRuntimeInitialized?: () => any;
postRun?: (() => any)[];
postRun?: (() => any)[] | (() => any);
onAbort?: {
(error: any): void;
};
}
declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
declare function mono_wasm_runtime_ready(): void;
declare type MonoConfig = {
assemblyRootFolder?: string;
assets?: AssetEntry[];
/**
* debugLevel > 0 enables debugging and sets the debug log level to debugLevel
* debugLevel == 0 disables debugging and enables interpreter optimizations
* debugLevel < 0 enabled debugging and disables debug logging.
*/
debugLevel?: number;
maxParallelDownloads?: number;
globalizationMode?: GlobalizationMode;
diagnosticTracing?: boolean;
remoteSources?: string[];
environmentVariables?: {
[i: string]: string;
};
runtimeOptions?: string[];
aotProfilerOptions?: AOTProfilerOptions;
coverageProfilerOptions?: CoverageProfilerOptions;
ignorePdbLoadErrors?: boolean;
waitForDebugger?: number;
};
interface ResourceRequest {
name: string;
behavior: AssetBehaviours;
resolvedUrl?: string;
hash?: string;
}
interface AssetEntry extends ResourceRequest {
virtualPath?: string;
culture?: string;
loadRemote?: boolean;
isOptional?: boolean;
buffer?: ArrayBuffer;
pending?: LoadingResource;
}
declare type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm";
declare type GlobalizationMode = "icu" | // load ICU globalization data from any runtime assets with behavior "icu".
"invariant" | // operate in invariant globalization mode.
"auto";
declare type AOTProfilerOptions = {
writeAt?: string;
sendTo?: string;
};
declare type CoverageProfilerOptions = {
writeAt?: string;
sendTo?: string;
};
declare type DotnetModuleConfig = {
disableDotnet6Compatibility?: boolean;
config?: MonoConfig;
configSrc?: string;
onConfigLoaded?: (config: MonoConfig) => void | Promise<void>;
onDotnetReady?: () => void | Promise<void>;
imports?: any;
exports?: string[];
downloadResource?: (request: ResourceRequest) => LoadingResource | undefined;
} & Partial<EmscriptenModule>;
interface LoadingResource {
name: string;
url: string;
response: Promise<Response>;
}
/**
* Allocates a block of memory that can safely contain pointers into the managed heap.
* The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers.
* Once you are done using the root buffer, you must call its release() method.
* For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
*/
declare function mono_wasm_new_root_buffer(capacity: number, name?: string): WasmRootBuffer;
/**
* Allocates a WasmRoot pointing to a root provided and controlled by external code. Typicaly on managed stack.
* Releasing this root will not de-allocate the root space. You still need to call .release().
*/
declare function mono_wasm_new_external_root<T extends MonoObject>(address: VoidPtr | MonoObjectRef): WasmRoot<T>;
/**
* Allocates temporary storage for a pointer into the managed heap.
* Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected.
* If you already have a managed pointer you can pass it as an argument to initialize the temporary storage.
* The result object has get() and set(value) methods, along with a .value property.
* When you are done using the root you must call its .release() method.
*/
declare function mono_wasm_new_root<T extends MonoObject>(value?: T | undefined): WasmRoot<T>;
/**
* Releases 1 or more root or root buffer objects.
* Multiple objects may be passed on the argument list.
* 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
* even if you are not sure all of your roots have been created yet.
* @param {... WasmRoot} roots
*/
declare function mono_wasm_release_roots(...args: WasmRoot<any>[]): void;
declare class WasmRootBuffer {
private __count;
private length;
private __offset;
private __offset32;
private __handle;
private __ownsAllocation;
constructor(offset: VoidPtr, capacity: number, ownsAllocation: boolean, name?: string);
_throw_index_out_of_range(): void;
_check_in_range(index: number): void;
get_address(index: number): MonoObjectRef;
get_address_32(index: number): number;
get(index: number): ManagedPointer;
set(index: number, value: ManagedPointer): ManagedPointer;
copy_value_from_address(index: number, sourceAddress: MonoObjectRef): void;
_unsafe_get(index: number): number;
_unsafe_set(index: number, value: ManagedPointer | NativePointer): void;
clear(): void;
release(): void;
toString(): string;
}
interface WasmRoot<T extends MonoObject> {
get_address(): MonoObjectRef;
get_address_32(): number;
get address(): MonoObjectRef;
get(): T;
set(value: T): T;
get value(): T;
set value(value: T);
copy_from_address(source: MonoObjectRef): void;
copy_to_address(destination: MonoObjectRef): void;
copy_from(source: WasmRoot<T>): void;
copy_to(destination: WasmRoot<T>): void;
valueOf(): T;
clear(): void;
release(): void;
toString(): string;
interface APIType {
runMain: (mainAssemblyName: string, args: string[]) => Promise<number>;
runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise<void>;
setEnvironmentVariable: (name: string, value: string) => void;
getAssemblyExports(assemblyName: string): Promise<any>;
setModuleImports(moduleName: string, moduleImports: any): void;
getConfig: () => MonoConfig;
setHeapB32: (offset: NativePointer, value: number | boolean) => void;
setHeapU8: (offset: NativePointer, value: number) => void;
setHeapU16: (offset: NativePointer, value: number) => void;
setHeapU32: (offset: NativePointer, value: NativePointer | number) => void;
setHeapI8: (offset: NativePointer, value: number) => void;
setHeapI16: (offset: NativePointer, value: number) => void;
setHeapI32: (offset: NativePointer, value: number) => void;
setHeapI52: (offset: NativePointer, value: number) => void;
setHeapU52: (offset: NativePointer, value: number) => void;
setHeapI64Big: (offset: NativePointer, value: bigint) => void;
setHeapF32: (offset: NativePointer, value: number) => void;
setHeapF64: (offset: NativePointer, value: number) => void;
getHeapB32: (offset: NativePointer) => boolean;
getHeapU8: (offset: NativePointer) => number;
getHeapU16: (offset: NativePointer) => number;
getHeapU32: (offset: NativePointer) => number;
getHeapI8: (offset: NativePointer) => number;
getHeapI16: (offset: NativePointer) => number;
getHeapI32: (offset: NativePointer) => number;
getHeapI52: (offset: NativePointer) => number;
getHeapU52: (offset: NativePointer) => number;
getHeapI64Big: (offset: NativePointer) => bigint;
getHeapF32: (offset: NativePointer) => number;
getHeapF64: (offset: NativePointer) => number;
}
declare type DotnetPublicAPI = {
/**
* @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts
*/
MONO: any;
/**
* @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts
*/
BINDING: any;
INTERNAL: any;
Module: EmscriptenModule;
runtimeId: number;
runtimeBuildInfo: {
productVersion: string;
buildConfiguration: string;
} & APIType;
};
interface IDisposable {
dispose(): void;
get isDisposed(): boolean;
}
declare class ManagedObject implements IDisposable {
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
declare class ManagedError extends Error implements IDisposable {
constructor(message: string);
get stack(): string | undefined;
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
declare const enum MemoryViewType {
Byte = 0,
Int32 = 1,
@ -171,365 +201,6 @@ interface IMemoryView {
get byteLength(): number;
}
interface MonoObject extends ManagedPointer {
__brandMonoObject: "MonoObject";
}
interface MonoString extends MonoObject {
__brand: "MonoString";
}
interface MonoArray extends MonoObject {
__brand: "MonoArray";
}
interface MonoObjectRef extends ManagedPointer {
__brandMonoObjectRef: "MonoObjectRef";
}
declare type MonoConfig = {
isError?: false;
assembly_root?: string;
assets?: AssetEntry[];
/**
* Either this or enable_debugging needs to be set
* debug_level > 0 enables debugging and sets the debug log level to debug_level
* debug_level == 0 disables debugging and enables interpreter optimizations
* debug_level < 0 enabled debugging and disables debug logging.
*/
debug_level?: number;
enable_debugging?: number;
globalization_mode?: GlobalizationMode;
diagnostic_tracing?: boolean;
remote_sources?: string[];
max_parallel_downloads?: number;
environment_variables?: {
[i: string]: string;
};
runtime_options?: string[];
aot_profiler_options?: AOTProfilerOptions;
coverage_profiler_options?: CoverageProfilerOptions;
diagnostic_options?: DiagnosticOptions;
ignore_pdb_load_errors?: boolean;
wait_for_debugger?: number;
};
declare type MonoConfigError = {
isError: true;
message: string;
error: any;
};
interface ResourceRequest {
name: string;
behavior: AssetBehaviours;
resolvedUrl?: string;
hash?: string;
}
interface AssetEntry extends ResourceRequest {
virtual_path?: string;
culture?: string;
load_remote?: boolean;
is_optional?: boolean;
buffer?: ArrayBuffer;
pending?: LoadingResource;
}
declare type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm";
declare type GlobalizationMode = "icu" | // load ICU globalization data from any runtime assets with behavior "icu".
"invariant" | // operate in invariant globalization mode.
"auto";
declare type AOTProfilerOptions = {
write_at?: string;
send_to?: string;
};
declare type CoverageProfilerOptions = {
write_at?: string;
send_to?: string;
};
declare type DiagnosticOptions = {
sessions?: EventPipeSessionOptions[];
server?: DiagnosticServerOptions;
};
interface EventPipeSessionOptions {
collectRundownEvents?: boolean;
providers: string;
}
declare type DiagnosticServerOptions = {
connect_url: string;
suspend: string | boolean;
};
declare type DotnetModuleConfig = {
disableDotnet6Compatibility?: boolean;
config?: MonoConfig;
configSrc?: string;
onConfigLoaded?: (config: MonoConfig) => void | Promise<void>;
onDotnetReady?: () => void | Promise<void>;
imports?: DotnetModuleConfigImports;
exports?: string[];
downloadResource?: (request: ResourceRequest) => LoadingResource;
} & Partial<EmscriptenModule>;
declare type DotnetModuleConfigImports = {
require?: (name: string) => any;
fetch?: (url: string) => Promise<Response>;
fs?: {
promises?: {
readFile?: (path: string) => Promise<string | Buffer>;
};
readFileSync?: (path: string, options: any | undefined) => string;
};
crypto?: {
randomBytes?: (size: number) => Buffer;
};
ws?: WebSocket & {
Server: any;
};
path?: {
normalize?: (path: string) => string;
dirname?: (path: string) => string;
};
url?: any;
};
interface LoadingResource {
name: string;
url: string;
response: Promise<Response>;
}
declare type EventPipeSessionID = bigint;
interface DotnetPublicAPI {
MONO: MONOType;
BINDING: BINDINGType;
INTERNAL: any;
EXPORTS: any;
IMPORTS: any;
Module: EmscriptenModule;
RuntimeId: number;
RuntimeBuildInfo: {
ProductVersion: string;
Configuration: string;
};
}
declare const eventLevel: {
readonly LogAlways: 0;
readonly Critical: 1;
readonly Error: 2;
readonly Warning: 3;
readonly Informational: 4;
readonly Verbose: 5;
};
declare type EventLevel = typeof eventLevel;
declare type UnnamedProviderConfiguration = Partial<{
keyword_mask: string | 0;
level: number;
args: string;
}>;
interface ProviderConfiguration extends UnnamedProviderConfiguration {
name: string;
}
declare class SessionOptionsBuilder {
private _rundown?;
private _providers;
constructor();
static get Empty(): SessionOptionsBuilder;
static get DefaultProviders(): SessionOptionsBuilder;
setRundownEnabled(enabled: boolean): SessionOptionsBuilder;
addProvider(provider: ProviderConfiguration): SessionOptionsBuilder;
addRuntimeProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder;
addRuntimePrivateProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder;
addSampleProfilerProvider(overrideOptions?: UnnamedProviderConfiguration): SessionOptionsBuilder;
build(): EventPipeSessionOptions;
}
interface EventPipeSession {
get sessionID(): EventPipeSessionID;
start(): void;
stop(): void;
getTraceBlob(): Blob;
}
interface Diagnostics {
EventLevel: EventLevel;
SessionOptionsBuilder: typeof SessionOptionsBuilder;
createEventPipeSession(options?: EventPipeSessionOptions): EventPipeSession | null;
getStartupSessions(): (EventPipeSession | null)[];
}
declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean;
declare function mono_wasm_get_assembly_exports(assembly: string): Promise<any>;
declare type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
declare type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
declare function setB32(offset: _MemOffset, value: number | boolean): void;
declare function setU8(offset: _MemOffset, value: number): void;
declare function setU16(offset: _MemOffset, value: number): void;
declare function setU32(offset: _MemOffset, value: _NumberOrPointer): void;
declare function setI8(offset: _MemOffset, value: number): void;
declare function setI16(offset: _MemOffset, value: number): void;
declare function setI32(offset: _MemOffset, value: number): void;
/**
* Throws for values which are not 52 bit integer. See Number.isSafeInteger()
*/
declare function setI52(offset: _MemOffset, value: number): void;
/**
* Throws for values which are not 52 bit integer or are negative. See Number.isSafeInteger().
*/
declare function setU52(offset: _MemOffset, value: number): void;
declare function setI64Big(offset: _MemOffset, value: bigint): void;
declare function setF32(offset: _MemOffset, value: number): void;
declare function setF64(offset: _MemOffset, value: number): void;
declare function getB32(offset: _MemOffset): boolean;
declare function getU8(offset: _MemOffset): number;
declare function getU16(offset: _MemOffset): number;
declare function getU32(offset: _MemOffset): number;
declare function getI8(offset: _MemOffset): number;
declare function getI16(offset: _MemOffset): number;
declare function getI32(offset: _MemOffset): number;
/**
* Throws for Number.MIN_SAFE_INTEGER > value > Number.MAX_SAFE_INTEGER
*/
declare function getI52(offset: _MemOffset): number;
/**
* Throws for 0 > value > Number.MAX_SAFE_INTEGER
*/
declare function getU52(offset: _MemOffset): number;
declare function getI64Big(offset: _MemOffset): bigint;
declare function getF32(offset: _MemOffset): number;
declare function getF64(offset: _MemOffset): number;
declare function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr;
declare function mono_run_main_and_exit(main_assembly_name: string, args: string[]): Promise<void>;
declare function mono_run_main(main_assembly_name: string, args: string[]): Promise<number>;
declare function mono_wasm_setenv(name: string, value: string): void;
declare function mono_wasm_load_data_archive(data: Uint8Array, prefix: string): boolean;
/**
* Loads the mono config file (typically called mono-config.json) asynchroniously
* Note: the run dependencies are so emsdk actually awaits it in order.
*
* @param {string} configFilePath - relative path to the config file
* @throws Will throw an error if the config file loading fails
*/
declare function mono_wasm_load_config(configFilePath: string): Promise<void>;
/**
* @deprecated
*/
declare function mono_load_runtime_and_bcl_args(cfg?: MonoConfig | MonoConfigError | undefined): Promise<void>;
/**
* @deprecated Not GC or thread safe
*/
declare function conv_string(mono_obj: MonoString): string | null;
declare function conv_string_root(root: WasmRoot<MonoString>): string | null;
declare function js_string_to_mono_string_root(string: string, result: WasmRoot<MonoString>): void;
/**
* @deprecated Not GC or thread safe
*/
declare function js_string_to_mono_string(string: string): MonoString;
declare function unbox_mono_obj(mono_obj: MonoObject): any;
declare function unbox_mono_obj_root(root: WasmRoot<any>): any;
declare function mono_array_to_js_array(mono_array: MonoArray): any[] | null;
declare function mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>): any[] | null;
/**
* @deprecated Not GC or thread safe. For blazor use only
*/
declare function js_to_mono_obj(js_obj: any): MonoObject;
declare function js_to_mono_obj_root(js_obj: any, result: WasmRoot<MonoObject>, should_add_in_flight: boolean): void;
declare function js_typed_array_to_array_root(js_obj: any, result: WasmRoot<MonoArray>): void;
/**
* @deprecated Not GC or thread safe
*/
declare function js_typed_array_to_array(js_obj: any): MonoArray;
declare function mono_bind_static_method(fqn: string, signature?: string): Function;
declare function mono_call_assembly_entry_point(assembly: string, args?: any[], signature?: string): number;
declare type BINDINGType = {
bind_static_method: typeof mono_bind_static_method;
call_assembly_entry_point: typeof mono_call_assembly_entry_point;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_new: (size: number) => MonoArray;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void;
/**
* @deprecated Not GC or thread safe
*/
js_string_to_mono_string: typeof js_string_to_mono_string;
/**
* @deprecated Not GC or thread safe
*/
js_typed_array_to_array: typeof js_typed_array_to_array;
/**
* @deprecated Not GC or thread safe
*/
mono_array_to_js_array: typeof mono_array_to_js_array;
/**
* @deprecated Not GC or thread safe
*/
js_to_mono_obj: typeof js_to_mono_obj;
/**
* @deprecated Not GC or thread safe
*/
conv_string: typeof conv_string;
/**
* @deprecated Not GC or thread safe
*/
unbox_mono_obj: typeof unbox_mono_obj;
mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void;
mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void;
js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
js_to_mono_obj_root: typeof js_to_mono_obj_root;
conv_string_root: typeof conv_string_root;
unbox_mono_obj_root: typeof unbox_mono_obj_root;
mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
};
declare type MONOType = {
mono_wasm_setenv: typeof mono_wasm_setenv;
mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
mono_wasm_load_config: typeof mono_wasm_load_config;
mono_load_runtime_and_bcl_args: typeof mono_load_runtime_and_bcl_args;
mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
mono_wasm_new_root: typeof mono_wasm_new_root;
mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
mono_wasm_release_roots: typeof mono_wasm_release_roots;
mono_run_main: typeof mono_run_main;
mono_run_main_and_exit: typeof mono_run_main_and_exit;
mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number;
mono_wasm_load_runtime: (unused: string, debug_level: number) => void;
config: MonoConfig | MonoConfigError;
loaded_files: string[];
setB32: typeof setB32;
setI8: typeof setI8;
setI16: typeof setI16;
setI32: typeof setI32;
setI52: typeof setI52;
setU52: typeof setU52;
setI64Big: typeof setI64Big;
setU8: typeof setU8;
setU16: typeof setU16;
setU32: typeof setU32;
setF32: typeof setF32;
setF64: typeof setF64;
getB32: typeof getB32;
getI8: typeof getI8;
getI16: typeof getI16;
getI32: typeof getI32;
getI52: typeof getI52;
getU52: typeof getU52;
getI64Big: typeof getI64Big;
getU8: typeof getU8;
getU16: typeof getU16;
getU32: typeof getU32;
getF32: typeof getF32;
getF64: typeof getF64;
diagnostics: Diagnostics;
};
declare function createDotnetRuntime(moduleFactory: DotnetModuleConfig | ((api: DotnetPublicAPI) => DotnetModuleConfig)): Promise<DotnetPublicAPI>;
declare type CreateDotnetRuntimeType = typeof createDotnetRuntime;
declare global {
@ -564,5 +235,22 @@ declare class ArraySegment implements IMemoryView, IDisposable {
get length(): number;
get byteLength(): number;
}
/**
* Represents proxy to the System.Exception
*/
declare class ManagedError extends Error implements IDisposable {
get stack(): string | undefined;
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
/**
* Represents proxy to the System.Object
*/
declare class ManagedObject implements IDisposable {
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
export { ArraySegment, AssetBehaviours, AssetEntry, BINDINGType, CreateDotnetRuntimeType, DotnetModuleConfig, DotnetPublicAPI, EmscriptenModule, IMemoryView, LoadingResource, MONOType, ManagedError, ManagedObject, MemoryViewType, MonoArray, MonoConfig, MonoObject, MonoString, ResourceRequest, Span, VoidPtr, createDotnetRuntime as default };
export { APIType, ArraySegment, AssetBehaviours, AssetEntry, CreateDotnetRuntimeType, DotnetModuleConfig, DotnetPublicAPI, EmscriptenModule, IMemoryView, LoadingResource, ManagedError, ManagedObject, MemoryViewType, MonoConfig, NativePointer, ResourceRequest, Span, createDotnetRuntime as default };

View File

@ -33,7 +33,7 @@ if (ENVIRONMENT_IS_NODE) {
}
let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports(
{ isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise },
{ mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_exports: EXPORTS, marshaled_imports: IMPORTS },
{ mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_imports: IMPORTS },
__dotnet_replacements);
updateGlobalBufferAndViews = __dotnet_replacements.updateGlobalBufferAndViews;
var fetch = __dotnet_replacements.fetch;

View File

@ -1,10 +1,10 @@
const MONO = {}, BINDING = {}, INTERNAL = {}, IMPORTS = {}, EXPORTS = {};
const MONO = {}, BINDING = {}, INTERNAL = {}, IMPORTS = {};
let ENVIRONMENT_IS_GLOBAL = false;
var require = require || undefined;
var __dirname = __dirname || '';
if (typeof createDotnetRuntime === "function") {
Module = { ready: Module.ready };
const extension = createDotnetRuntime({ MONO, BINDING, INTERNAL, IMPORTS, EXPORTS, Module })
const extension = createDotnetRuntime({ MONO, BINDING, INTERNAL, Module, IMPORTS })
if (extension.ready) {
throw new Error("MONO_WASM: Module.ready couldn't be redefined.")
}

View File

@ -0,0 +1,46 @@
import { APIType } from "./exports";
import { runtimeHelpers } from "./imports";
import { mono_wasm_get_assembly_exports } from "./invoke-cs";
import { mono_wasm_set_module_imports } from "./invoke-js";
import { getB32, getF32, getF64, getI16, getI32, getI52, getI64Big, getI8, getU16, getU32, getU52, getU8, setB32, setF32, setF64, setI16, setI32, setI52, setI64Big, setI8, setU16, setU32, setU52, setU8 } from "./memory";
import { mono_run_main, mono_run_main_and_exit } from "./run";
import { mono_wasm_setenv } from "./startup";
import { MonoConfig } from "./types";
export function export_api(): any {
const api: APIType = {
runMain: mono_run_main,
runMainAndExit: mono_run_main_and_exit,
setEnvironmentVariable: mono_wasm_setenv,
getAssemblyExports: mono_wasm_get_assembly_exports,
setModuleImports: mono_wasm_set_module_imports,
getConfig: (): MonoConfig => {
return runtimeHelpers.config;
},
setHeapB32: setB32,
setHeapU8: setU8,
setHeapU16: setU16,
setHeapU32: setU32,
setHeapI8: setI8,
setHeapI16: setI16,
setHeapI32: setI32,
setHeapI52: setI52,
setHeapU52: setU52,
setHeapI64Big: setI64Big,
setHeapF32: setF32,
setHeapF64: setF64,
getHeapB32: getB32,
getHeapU8: getU8,
getHeapU16: getU16,
getHeapU32: getU32,
getHeapI8: getI8,
getHeapI16: getI16,
getHeapI32: getI32,
getHeapI52: getI52,
getHeapU52: getU52,
getHeapI64Big: getI64Big,
getHeapF32: getF32,
getHeapF64: getF64,
};
return api;
}

View File

@ -1,10 +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 { BINDINGType, MONOType } from "./net6-legacy/exports-legacy";
import { IDisposable, IMemoryView, ManagedError, ManagedObject, MemoryViewType } from "./marshal";
import { AssetBehaviours, AssetEntry, DotnetModuleConfig, DotnetPublicAPI, LoadingResource, MonoArray, MonoConfig, MonoObject, MonoString, ResourceRequest } from "./types";
import { EmscriptenModule, TypedArray, VoidPtr } from "./types/emscripten";
import { APIType, DotnetPublicAPI } from "./exports";
import { IDisposable, IMemoryView, MemoryViewType } from "./marshal";
import { AssetBehaviours, AssetEntry, DotnetModuleConfig, LoadingResource, MonoConfig, ResourceRequest } from "./types";
import { EmscriptenModule, NativePointer, TypedArray } from "./types/emscripten";
// -----------------------------------------------------------
// this files has all public exports from the dotnet.js module
@ -51,11 +51,28 @@ declare class ArraySegment implements IMemoryView, IDisposable {
get byteLength(): number;
}
/**
* Represents proxy to the System.Exception
*/
declare class ManagedError extends Error implements IDisposable {
get stack(): string | undefined;
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
/**
* Represents proxy to the System.Object
*/
declare class ManagedObject implements IDisposable {
dispose(): void;
get isDisposed(): boolean;
toString(): string;
}
export {
VoidPtr,
MonoObject, MonoString, MonoArray,
BINDINGType, MONOType, EmscriptenModule,
DotnetPublicAPI, DotnetModuleConfig, CreateDotnetRuntimeType, MonoConfig,
EmscriptenModule, NativePointer,
DotnetPublicAPI, APIType, DotnetModuleConfig, CreateDotnetRuntimeType, MonoConfig,
AssetEntry, ResourceRequest, LoadingResource, AssetBehaviours,
IMemoryView, MemoryViewType, ManagedObject, ManagedError, Span, ArraySegment
};

View File

@ -2,11 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
import ProductVersion from "consts:productVersion";
import Configuration from "consts:configuration";
import BuildConfiguration from "consts:configuration";
import MonoWasmThreads from "consts:monoWasmThreads";
import { ENVIRONMENT_IS_PTHREAD, set_imports_exports } from "./imports";
import { DotnetModule, is_nullish, DotnetPublicAPI, EarlyImports, EarlyExports, EarlyReplacements } from "./types";
import { DotnetModule, is_nullish, EarlyImports, EarlyExports, EarlyReplacements, MonoConfig } from "./types";
import { configure_emscripten_startup, mono_wasm_pthread_worker_init } from "./startup";
import { mono_bind_static_method } from "./net6-legacy/method-calls";
@ -15,6 +15,8 @@ import { export_binding_api, export_mono_api } from "./net6-legacy/exports-legac
import { export_internal } from "./exports-internal";
import { export_linker } from "./exports-linker";
import { init_polyfills } from "./polyfills";
import { EmscriptenModule, NativePointer } from "./types/emscripten";
import { export_api } from "./export-api";
export const __initializeImportsAndExports: any = initializeImportsAndExports; // don't want to export the type
export let __linker_exports: any = null;
@ -41,19 +43,20 @@ function initializeImportsAndExports(
Object.assign(exports.mono, export_mono_api());
Object.assign(exports.binding, export_binding_api());
Object.assign(exports.internal, export_internal());
const API = export_api();
__linker_exports = export_linker();
exportedAPI = <any>{
MONO: exports.mono,
BINDING: exports.binding,
INTERNAL: exports.internal,
EXPORTS: exports.marshaled_exports,
IMPORTS: exports.marshaled_imports,
Module: module,
RuntimeBuildInfo: {
ProductVersion,
Configuration
}
runtimeBuildInfo: {
productVersion: ProductVersion,
buildConfiguration: BuildConfiguration
},
...API,
};
if (exports.module.__undefinedConfig) {
module.disableDotnet6Compatibility = true;
@ -78,7 +81,7 @@ function initializeImportsAndExports(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
module.mono_bind_static_method = (fqn: string, signature: string/*ArgsMarshalString*/): Function => {
console.warn("MONO_WASM: Module.mono_bind_static_method is obsolete, please use BINDING.bind_static_method instead");
console.warn("MONO_WASM: Module.mono_bind_static_method is obsolete, please use [JSExportAttribute] interop instead");
return mono_bind_static_method(fqn, signature);
};
@ -150,9 +153,9 @@ class RuntimeList {
private list: { [runtimeId: number]: WeakRef<DotnetPublicAPI> } = {};
public registerRuntime(api: DotnetPublicAPI): number {
api.RuntimeId = Object.keys(this.list).length;
this.list[api.RuntimeId] = create_weak_ref(api);
return api.RuntimeId;
api.runtimeId = Object.keys(this.list).length;
this.list[api.runtimeId] = create_weak_ref(api);
return api.runtimeId;
}
public getRuntime(runtimeId: number): DotnetPublicAPI | undefined {
@ -164,3 +167,56 @@ class RuntimeList {
export function get_dotnet_instance(): DotnetPublicAPI {
return exportedAPI;
}
export interface APIType {
runMain: (mainAssemblyName: string, args: string[]) => Promise<number>,
runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise<void>,
setEnvironmentVariable: (name: string, value: string) => void,
getAssemblyExports(assemblyName: string): Promise<any>,
setModuleImports(moduleName: string, moduleImports: any): void,
getConfig: () => MonoConfig,
setHeapB32: (offset: NativePointer, value: number | boolean) => void,
setHeapU8: (offset: NativePointer, value: number) => void,
setHeapU16: (offset: NativePointer, value: number) => void,
setHeapU32: (offset: NativePointer, value: NativePointer | number) => void,
setHeapI8: (offset: NativePointer, value: number) => void,
setHeapI16: (offset: NativePointer, value: number) => void,
setHeapI32: (offset: NativePointer, value: number) => void,
setHeapI52: (offset: NativePointer, value: number) => void,
setHeapU52: (offset: NativePointer, value: number) => void,
setHeapI64Big: (offset: NativePointer, value: bigint) => void,
setHeapF32: (offset: NativePointer, value: number) => void,
setHeapF64: (offset: NativePointer, value: number) => void,
getHeapB32: (offset: NativePointer) => boolean,
getHeapU8: (offset: NativePointer) => number,
getHeapU16: (offset: NativePointer) => number,
getHeapU32: (offset: NativePointer) => number,
getHeapI8: (offset: NativePointer) => number,
getHeapI16: (offset: NativePointer) => number,
getHeapI32: (offset: NativePointer) => number,
getHeapI52: (offset: NativePointer) => number,
getHeapU52: (offset: NativePointer) => number,
getHeapI64Big: (offset: NativePointer) => bigint,
getHeapF32: (offset: NativePointer) => number,
getHeapF64: (offset: NativePointer) => number,
}
// this represents visibility in the javascript
// like https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts
export type DotnetPublicAPI = {
/**
* @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts
*/
MONO: any,
/**
* @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts
*/
BINDING: any,
INTERNAL: any,
Module: EmscriptenModule,
runtimeId: number,
runtimeBuildInfo: {
productVersion: string,
buildConfiguration: string,
} & APIType
}

View File

@ -26,24 +26,24 @@ export function mono_wasm_get_icudt_name(culture: string): string {
}
// Performs setup for globalization.
// @globalization_mode is one of "icu", "invariant", or "auto".
// @globalizationMode is one of "icu", "invariant", or "auto".
// "auto" will use "icu" if any ICU data archives have been loaded,
// otherwise "invariant".
export function mono_wasm_globalization_init(): void {
const config = Module.config as MonoConfig;
let invariantMode = false;
if (!config.globalization_mode)
config.globalization_mode = "auto";
if (config.globalization_mode === "invariant")
if (!config.globalizationMode)
config.globalizationMode = "auto";
if (config.globalizationMode === "invariant")
invariantMode = true;
if (!invariantMode) {
if (num_icu_assets_loaded_successfully > 0) {
if (runtimeHelpers.diagnostic_tracing) {
if (runtimeHelpers.diagnosticTracing) {
console.debug("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode");
}
} else if (config.globalization_mode !== "icu") {
if (runtimeHelpers.diagnostic_tracing) {
} else if (config.globalizationMode !== "icu") {
if (runtimeHelpers.diagnosticTracing) {
console.debug("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode");
}
invariantMode = true;

View File

@ -4,7 +4,7 @@
/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="./types/v8.d.ts" />
import { BINDINGType, MONOType } from "./net6-legacy/exports-legacy";
import { BINDINGType, MONOType } from "./net6-legacy/export-types";
import { DotnetModule, EarlyExports, EarlyImports, MonoConfig, RuntimeHelpers } from "./types";
import { EmscriptenModule } from "./types/emscripten";
@ -13,7 +13,6 @@ export let Module: EmscriptenModule & DotnetModule;
export let MONO: MONOType;
export let BINDING: BINDINGType;
export let INTERNAL: any;
export let EXPORTS: any;
export let IMPORTS: any;
// these are imported and re-exported from emscripten internals
@ -33,9 +32,6 @@ export function set_imports_exports(
INTERNAL = exports.internal;
Module = exports.module;
EXPORTS = exports.marshaled_exports; // [JSExport]
IMPORTS = exports.marshaled_imports; // [JSImport]
ENVIRONMENT_IS_NODE = imports.isNode;
ENVIRONMENT_IS_SHELL = imports.isShell;
ENVIRONMENT_IS_WEB = imports.isWeb;
@ -69,7 +65,6 @@ export const runtimeHelpers: RuntimeHelpers = <any>{
MONO.config = value;
Module.config = value;
},
diagnostic_tracing: false,
enable_debugging: false,
diagnosticTracing: false,
fetch: null
};

View File

@ -1,18 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import { EXPORTS, Module, runtimeHelpers } from "./imports";
import { Module, runtimeHelpers } from "./imports";
import { generate_arg_marshal_to_cs } from "./marshal-to-cs";
import { marshal_exception_to_js, generate_arg_marshal_to_js } from "./marshal-to-js";
import {
JSMarshalerArguments, JavaScriptMarshalerArgSize, JSFunctionSignature,
JavaScriptMarshalerArgSize,
JSMarshalerTypeSize, JSMarshalerSignatureHeaderSize,
get_arg, get_sig,
get_signature_argument_count, is_args_exception, bound_cs_function_symbol, get_signature_version, MarshalerType, alloc_stack_frame,
} from "./marshal";
import { mono_wasm_new_external_root } from "./roots";
import { conv_string, conv_string_root } from "./strings";
import { mono_assert, MonoObjectRef, MonoStringRef, MonoString, MonoObject, MonoMethod } from "./types";
import { mono_assert, MonoObjectRef, MonoStringRef, MonoString, MonoObject, MonoMethod, JSMarshalerArguments, JSFunctionSignature } from "./types";
import { Int32Ptr } from "./types/emscripten";
import cwraps from "./cwraps";
import { assembly_load } from "./class-loader";
@ -31,7 +31,7 @@ export function mono_wasm_bind_cs_function(fully_qualified_name: MonoStringRef,
const js_fqn = conv_string_root(fqn_root)!;
mono_assert(js_fqn, "fully_qualified_name must be string");
if (runtimeHelpers.diagnostic_tracing) {
if (runtimeHelpers.diagnosticTracing) {
console.debug(`MONO_WASM: Binding [JSExport] ${js_fqn}`);
}
@ -119,30 +119,9 @@ export function invoke_method_and_handle_exception(method: MonoMethod, args: JSM
}
export const exportsByAssembly: Map<string, any> = new Map();
function _walk_exports_to_set_function(assembly: string, namespace: string, classname: string, methodname: string, signature_hash: number, fn: Function): void {
let scope: any = EXPORTS;
const parts = `${namespace}.${classname}`.replace(/\//g, ".").split(".");
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (part != "") {
let newscope = scope[part];
if (typeof newscope === "undefined") {
newscope = {};
scope[part] = newscope;
}
mono_assert(newscope, () => `${part} not found while looking up ${classname}`);
scope = newscope;
}
}
if (!scope[methodname]) {
scope[methodname] = fn;
}
scope[`${methodname}.${signature_hash}`] = fn;
// do it again for per assemly scope
let scope: any = undefined;
let assemblyScope = exportsByAssembly.get(assembly);
if (!assemblyScope) {
assemblyScope = {};

View File

@ -3,10 +3,10 @@
import { mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle } from "./gc-handles";
import { marshal_exception_to_cs, generate_arg_marshal_to_cs } from "./marshal-to-cs";
import { get_signature_argument_count, JSMarshalerArguments as JSMarshalerArguments, JavaScriptMarshalerArgSize, JSFunctionSignature as JSFunctionSignature, bound_js_function_symbol, JSMarshalerTypeSize, get_sig, JSMarshalerSignatureHeaderSize, get_signature_version, MarshalerType, get_signature_type } from "./marshal";
import { get_signature_argument_count, JavaScriptMarshalerArgSize, bound_js_function_symbol, JSMarshalerTypeSize, get_sig, JSMarshalerSignatureHeaderSize, get_signature_version, MarshalerType, get_signature_type } from "./marshal";
import { setI32 } from "./memory";
import { conv_string_root, js_string_to_mono_string_root } from "./strings";
import { mono_assert, JSHandle, MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "./types";
import { mono_assert, JSHandle, MonoObject, MonoObjectRef, MonoString, MonoStringRef, JSFunctionSignature, JSMarshalerArguments } from "./types";
import { Int32Ptr } from "./types/emscripten";
import { IMPORTS, INTERNAL, Module, runtimeHelpers } from "./imports";
import { generate_arg_marshal_to_js } from "./marshal-to-js";
@ -23,7 +23,7 @@ export function mono_wasm_bind_js_function(function_name: MonoStringRef, module_
const js_function_name = conv_string_root(function_name_root)!;
const js_module_name = conv_string_root(module_name_root)!;
if (runtimeHelpers.diagnostic_tracing) {
if (runtimeHelpers.diagnosticTracing) {
console.debug(`MONO_WASM: Binding [JSImport] ${js_function_name} from ${js_module_name}`);
}
const fn = mono_wasm_lookup_function(js_function_name, js_module_name);
@ -103,6 +103,12 @@ export function mono_wasm_invoke_bound_function(bound_function_js_handle: JSHand
bound_fn(args);
}
export function mono_wasm_set_module_imports(module_name: string, moduleImports: any) {
importedModules.set(module_name, moduleImports);
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: added module imports '${module_name}'`);
}
function mono_wasm_lookup_function(function_name: string, js_module_name: string): Function {
mono_assert(function_name && typeof function_name === "string", "function_name must be string");
@ -174,7 +180,7 @@ export async function dynamic_import(module_name: string, module_url: string): P
let promise = importedModulesPromises.get(module_name);
const newPromise = !promise;
if (newPromise) {
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: importing ES6 module '${module_name}' from '${module_url}'`);
promise = import(/* webpackIgnore: true */module_url);
importedModulesPromises.set(module_name, promise);
@ -182,7 +188,7 @@ export async function dynamic_import(module_name: string, module_url: string): P
const module = await promise;
if (newPromise) {
importedModules.set(module_name, module);
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: imported ES6 module '${module_name}' from '${module_url}'`);
}
return module;

View File

@ -1,27 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import { GCHandle, MonoMethod, mono_assert } from "./types";
import { GCHandle, MarshalerToCs, MarshalerToJs, MonoMethod, mono_assert } from "./types";
import cwraps from "./cwraps";
import { Module, runtimeHelpers } from "./imports";
import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerToCs, MarshalerToJs, MarshalerType, set_arg_type, set_gc_handle } from "./marshal";
import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerType, set_arg_type, set_gc_handle } from "./marshal";
import { invoke_method_and_handle_exception } from "./invoke-cs";
import { marshal_exception_to_cs } from "./marshal-to-cs";
// in all the exported internals methods, we use the same data structures for stack frame as normal full blow interop
// see src\libraries\System.Runtime.InteropServices.JavaScript\src\System\Runtime\InteropServices\JavaScript\Interop\JavaScriptExports.cs
export interface JavaScriptExports {
// the marshaled signature is: void ReleaseJSOwnedObjectByGCHandle(GCHandle gcHandle)
_release_js_owned_object_by_gc_handle(gc_handle: GCHandle): void;
// the marshaled signature is: GCHandle CreateTaskCallback()
_create_task_callback(): GCHandle;
// the marshaled signature is: void CompleteTask<T>(GCHandle holder, Exception? exceptionResult, T? result)
_complete_task(holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs): void;
// the marshaled signature is: TRes? CallDelegate<T1,T2,T3TRes>(GCHandle callback, T1? arg1, T2? arg2, T3? arg3)
_call_delegate(callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any,
res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs): any;
}
export function init_managed_exports(): void {
const anyModule = Module as any;
const exports_fqn_asm = "System.Runtime.InteropServices.JavaScript";

View File

@ -6,16 +6,16 @@ import cwraps from "./cwraps";
import { assert_not_disposed, cs_owned_js_handle_symbol, js_owned_gc_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, teardown_managed_proxy } from "./gc-handles";
import { Module, runtimeHelpers } from "./imports";
import {
JSMarshalerArgument, ManagedError,
ManagedError,
set_gc_handle, set_js_handle, set_arg_type, set_arg_i32, set_arg_f64, set_arg_i52, set_arg_f32, set_arg_i16, set_arg_u8, set_arg_b8, set_arg_date,
set_arg_length, get_arg, get_signature_type, get_signature_arg1_type, get_signature_arg2_type, cs_to_js_marshalers, js_to_cs_marshalers,
MarshalerToCs, MarshalerToJs, get_signature_res_type, JSMarshalerArguments, bound_js_function_symbol, set_arg_u16, JSMarshalerType, array_element_size,
get_signature_res_type, bound_js_function_symbol, set_arg_u16, array_element_size,
get_string_root, Span, ArraySegment, MemoryViewType, get_signature_arg3_type, MarshalerType, set_arg_i64_big, set_arg_intptr, IDisposable,
set_arg_element_type, ManagedObject
} from "./marshal";
import { _zero_region } from "./memory";
import { js_string_to_mono_string_root } from "./strings";
import { mono_assert, GCHandle, GCHandleNull } from "./types";
import { mono_assert, GCHandle, GCHandleNull, JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerToCs, MarshalerToJs } from "./types";
import { TypedArray } from "./types/emscripten";
export function initialize_marshalers_to_cs(): void {

View File

@ -6,7 +6,7 @@ import cwraps from "./cwraps";
import { _lookup_js_owned_object, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, setup_managed_proxy } from "./gc-handles";
import { Module, runtimeHelpers } from "./imports";
import {
ManagedObject, JSMarshalerArgument, ManagedError, JSMarshalerArguments, MarshalerToCs, MarshalerToJs, JSMarshalerType,
ManagedObject, ManagedError,
get_arg_gc_handle, get_arg_js_handle, get_arg_type, get_arg_i32, get_arg_f64, get_arg_i52, get_arg_i16, get_arg_u8, get_arg_f32,
get_arg_b8, get_arg_date, get_arg_length, set_js_handle, get_arg, set_arg_type,
get_signature_arg2_type, get_signature_arg1_type, get_signature_type, cs_to_js_marshalers, js_to_cs_marshalers,
@ -14,7 +14,7 @@ import {
ArraySegment, Span, MemoryViewType, get_signature_arg3_type, MarshalerType, get_arg_i64_big, get_arg_intptr, get_arg_element_type
} from "./marshal";
import { conv_string_root } from "./strings";
import { mono_assert, JSHandleNull, GCHandleNull } from "./types";
import { mono_assert, JSHandleNull, GCHandleNull, JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerToCs, MarshalerToJs } from "./types";
import { TypedArray } from "./types/emscripten";
export function initialize_marshalers_to_js(): void {

View File

@ -5,8 +5,8 @@ import { js_owned_gc_handle_symbol, teardown_managed_proxy } from "./gc-handles"
import { Module } from "./imports";
import { getF32, getF64, getI16, getI32, getI64Big, getU16, getU32, getU8, setF32, setF64, setI16, setI32, setI64Big, setU16, setU32, setU8 } from "./memory";
import { mono_wasm_new_external_root, WasmRoot } from "./roots";
import { mono_assert, GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull } from "./types";
import { CharPtr, NativePointer, TypedArray, VoidPtr } from "./types/emscripten";
import { mono_assert, GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerArguments, JSFunctionSignature, JSMarshalerType, JSMarshalerArgument, MarshalerToJs, MarshalerToCs } from "./types";
import { CharPtr, TypedArray, VoidPtr } from "./types/emscripten";
export const cs_to_js_marshalers = new Map<MarshalerType, MarshalerToJs>();
export const js_to_cs_marshalers = new Map<MarshalerType, MarshalerToCs>();
@ -39,22 +39,6 @@ export const JavaScriptMarshalerArgSize = 16;
export const JSMarshalerTypeSize = 32;
export const JSMarshalerSignatureHeaderSize = 4 + 4; // without Exception and Result
export interface JSMarshalerArguments extends NativePointer {
__brand: "JSMarshalerArguments"
}
export interface JSFunctionSignature extends NativePointer {
__brand: "JSFunctionSignatures"
}
export interface JSMarshalerType extends NativePointer {
__brand: "JSMarshalerType"
}
export interface JSMarshalerArgument extends NativePointer {
__brand: "JSMarshalerArgument"
}
export function alloc_stack_frame(size: number): JSMarshalerArguments {
const anyModule = Module as any;
const args = anyModule.stackAlloc(JavaScriptMarshalerArgSize * size);
@ -354,9 +338,6 @@ export class ManagedError extends Error implements IDisposable {
}
}
export type MarshalerToJs = (arg: JSMarshalerArgument, sig?: JSMarshalerType, res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs) => any;
export type MarshalerToCs = (arg: JSMarshalerArgument, value: any, sig?: JSMarshalerType, res_converter?: MarshalerToCs, arg1_converter?: MarshalerToJs, arg2_converter?: MarshalerToJs) => void;
export function get_signature_marshaler(signature: JSFunctionSignature, index: number): JSHandle {
mono_assert(signature, "Null signatures");
const sig = get_sig(signature, index);

View File

@ -38,43 +38,4 @@ await createDotnetRuntime(() => ({
}));
```
More complex scenario with using APIs, commented
```
import createDotnetRuntime from './dotnet.js'
export const { MONO, BINDING } = await createDotnetRuntime(({ MONO, BINDING, Module }) =>
// this is callback with no statement, the APIs are only empty shells here and are populated later.
({
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
onConfigLoaded: () => {
// This is called during emscripten `preInit` event, after we fetched config.
// Module.config is loaded and could be tweaked before application
Module.config.environment_variables["MONO_LOG_LEVEL"]="debug"
// here we could use API passed into this callback
// call some early available functions
MONO.mono_wasm_setenv("HELLO", "WORLD);
}
onDotnetReady: () => {
// Only when there is no `onRuntimeInitialized` override.
// This is called after all assets are loaded.
// It happens during emscripten `onRuntimeInitialized` after monoVm init + globalization + assemblies.
// This also matches when the top level promise is resolved.
// The original emscripten `Module.ready` promise is replaced with this.
// at this point both emscripten and monoVM are fully initialized.
Module.FS.chdir(processedArguments.working_dir);
},
onAbort: (error) => {
set_exit_code(1, error);
},
}));
// at this point both emscripten and monoVM are fully initialized.
// we could use the APIs returned and resolved from createDotnetRuntime promise
// both API exports are receiving the same API object instances, i.e. same `MONO` instance.
const run_all = BINDING.bind_static_method ("[debugger-test] DebuggerTest:run_all");
run_all();
```
For more complex scenario with using APIs see `src\mono\sample\wasm`

View File

@ -0,0 +1,265 @@
import { mono_wasm_runtime_ready } from "../debug";
import { mono_wasm_load_icu_data } from "../icu";
import { mono_wasm_get_assembly_exports } from "../invoke-cs";
import { mono_wasm_load_bytes_into_heap, setB32, setI8, setI16, setI32, setI52, setU52, setI64Big, setU8, setU16, setU32, setF32, setF64, getB32, getI8, getI16, getI32, getI52, getU52, getI64Big, getU8, getU16, getU32, getF32, getF64 } from "../memory";
import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_root, mono_wasm_release_roots } from "../roots";
import { mono_run_main, mono_run_main_and_exit } from "../run";
import { mono_wasm_setenv, mono_wasm_load_data_archive, mono_wasm_load_config } from "../startup";
import { js_string_to_mono_string, conv_string, js_string_to_mono_string_root, conv_string_root } from "../strings";
import { MonoArray, MonoObject, MonoObjectRef } from "../types";
import { VoidPtr } from "../types/emscripten";
import { mono_array_to_js_array, unbox_mono_obj, unbox_mono_obj_root, mono_array_root_to_js_array } from "./cs-to-js";
import { js_typed_array_to_array, js_to_mono_obj, js_typed_array_to_array_root, js_to_mono_obj_root } from "./js-to-cs";
import { mono_bind_static_method, mono_call_assembly_entry_point } from "./method-calls";
/**
* @deprecated Please use methods in top level API object instead
*/
export type BINDINGType = {
/**
* @deprecated Please use [JSExportAttribute] instead
*/
bind_static_method: typeof mono_bind_static_method;
/**
* @deprecated Please use runMain() instead
*/
call_assembly_entry_point: typeof mono_call_assembly_entry_point;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_new: (size: number) => MonoArray;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void;
/**
* @deprecated Not GC or thread safe
*/
js_string_to_mono_string: typeof js_string_to_mono_string;
/**
* @deprecated Not GC or thread safe
*/
js_typed_array_to_array: typeof js_typed_array_to_array;
/**
* @deprecated Not GC or thread safe
*/
mono_array_to_js_array: typeof mono_array_to_js_array;
/**
* @deprecated Not GC or thread safe
*/
js_to_mono_obj: typeof js_to_mono_obj;
/**
* @deprecated Not GC or thread safe
*/
conv_string: typeof conv_string;
/**
* @deprecated Not GC or thread safe
*/
unbox_mono_obj: typeof unbox_mono_obj;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
js_to_mono_obj_root: typeof js_to_mono_obj_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
conv_string_root: typeof conv_string_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
unbox_mono_obj_root: typeof unbox_mono_obj_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
}
/**
* @deprecated Please use methods in top level API object instead
*/
export type MONOType = {
/**
* @deprecated Please use setEnvironmentVariable() instead
*/
mono_wasm_setenv: typeof mono_wasm_setenv;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
/**
* @deprecated Please use configSrc instead
*/
mono_wasm_load_config: typeof mono_wasm_load_config;
/**
* @deprecated Please use runMain instead
*/
mono_load_runtime_and_bcl_args: Function;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_root: typeof mono_wasm_new_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
/**
* @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
*/
mono_wasm_release_roots: typeof mono_wasm_release_roots;
/**
* @deprecated Please use runMain instead
*/
mono_run_main: typeof mono_run_main;
/**
* @deprecated Please use runMainAndExit instead
*/
mono_run_main_and_exit: typeof mono_run_main_and_exit;
/**
* @deprecated Please use getAssemblyExports instead
*/
mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number;
/**
* @deprecated Please use config.assets instead
*/
mono_wasm_load_runtime: (unused: string, debugLevel: number) => void;
/**
* @deprecated Please use getConfig() instead
*/
config: any;
/**
* @deprecated Please use config.assets instead
*/
loaded_files: string[];
/**
* @deprecated Please use setHeapB32
*/
setB32: typeof setB32;
/**
* @deprecated Please use setHeapI8
*/
setI8: typeof setI8;
/**
* @deprecated Please use setHeapI16
*/
setI16: typeof setI16;
/**
* @deprecated Please use setHeapI32
*/
setI32: typeof setI32;
/**
* @deprecated Please use setHeapI52
*/
setI52: typeof setI52;
/**
* @deprecated Please use setHeapU52
*/
setU52: typeof setU52;
/**
* @deprecated Please use setHeapI64Big
*/
setI64Big: typeof setI64Big;
/**
* @deprecated Please use setHeapU8
*/
setU8: typeof setU8;
/**
* @deprecated Please use setHeapU16
*/
setU16: typeof setU16;
/**
* @deprecated Please use setHeapU32
*/
setU32: typeof setU32;
/**
* @deprecated Please use setHeapF32
*/
setF32: typeof setF32;
/**
* @deprecated Please use setHeapF64
*/
setF64: typeof setF64;
/**
* @deprecated Please use getHeapB32
*/
getB32: typeof getB32;
/**
* @deprecated Please use getHeapI8
*/
getI8: typeof getI8;
/**
* @deprecated Please use getHeapI16
*/
getI16: typeof getI16;
/**
* @deprecated Please use getHeapI32
*/
getI32: typeof getI32;
/**
* @deprecated Please use getHeapI52
*/
getI52: typeof getI52;
/**
* @deprecated Please use getHeapU52
*/
getU52: typeof getU52;
/**
* @deprecated Please use getHeapI64Big
*/
getI64Big: typeof getI64Big;
/**
* @deprecated Please use getHeapU8
*/
getU8: typeof getU8;
/**
* @deprecated Please use getHeapU16
*/
getU16: typeof getU16;
/**
* @deprecated Please use getHeapU32
*/
getU32: typeof getU32;
/**
* @deprecated Please use getHeapF32
*/
getF32: typeof getF32;
/**
* @deprecated Please use getHeapF64
*/
getF64: typeof getF64;
}

View File

@ -1,6 +1,5 @@
import cwraps from "../cwraps";
import { mono_wasm_runtime_ready } from "../debug";
import diagnostics, { Diagnostics } from "../diagnostics";
import { mono_wasm_load_icu_data } from "../icu";
import { runtimeHelpers } from "../imports";
import { mono_wasm_get_assembly_exports } from "../invoke-cs";
@ -9,16 +8,16 @@ import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_r
import { mono_run_main, mono_run_main_and_exit } from "../run";
import { mono_wasm_setenv, mono_wasm_load_data_archive, mono_wasm_load_config, mono_load_runtime_and_bcl_args } from "../startup";
import { js_string_to_mono_string, conv_string, js_string_to_mono_string_root, conv_string_root } from "../strings";
import { MonoArray, MonoConfig, MonoConfigError, MonoObject, MonoObjectRef } from "../types";
import { VoidPtr } from "../types/emscripten";
import { MonoConfig, MonoConfigError } from "../types";
import { mono_array_to_js_array, unbox_mono_obj, unbox_mono_obj_root, mono_array_root_to_js_array } from "./cs-to-js";
import { js_typed_array_to_array, js_to_mono_obj, js_typed_array_to_array_root, js_to_mono_obj_root } from "./js-to-cs";
import { mono_bind_static_method, mono_call_assembly_entry_point } from "./method-calls";
import { mono_wasm_load_runtime } from "../startup";
import { BINDINGType, MONOType } from "./export-types";
export function export_mono_api(): MONOType {
return {
// current "public" MONO API
// legacy MONO API
mono_wasm_setenv,
mono_wasm_load_bytes_into_heap,
mono_wasm_load_icu_data,
@ -66,9 +65,6 @@ export function export_mono_api(): MONOType {
getU32,
getF32,
getF64,
// Diagnostics
diagnostics
};
}
@ -80,7 +76,7 @@ export function cwraps_mono_api(mono: MONOType): void {
export function export_binding_api(): BINDINGType {
return {
//current "public" BINDING API
// legacy BINDING API
bind_static_method: mono_bind_static_method,
call_assembly_entry_point: mono_call_assembly_entry_point,
mono_obj_array_new: <any>null,
@ -111,97 +107,3 @@ export function cwraps_binding_api(binding: BINDINGType): void {
mono_obj_array_set_ref: cwraps.mono_wasm_obj_array_set_ref,
});
}
export type BINDINGType = {
bind_static_method: typeof mono_bind_static_method;
call_assembly_entry_point: typeof mono_call_assembly_entry_point;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_new: (size: number) => MonoArray;
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void;
/**
* @deprecated Not GC or thread safe
*/
js_string_to_mono_string: typeof js_string_to_mono_string;
/**
* @deprecated Not GC or thread safe
*/
js_typed_array_to_array: typeof js_typed_array_to_array;
/**
* @deprecated Not GC or thread safe
*/
mono_array_to_js_array: typeof mono_array_to_js_array;
/**
* @deprecated Not GC or thread safe
*/
js_to_mono_obj: typeof js_to_mono_obj;
/**
* @deprecated Not GC or thread safe
*/
conv_string: typeof conv_string;
/**
* @deprecated Not GC or thread safe
*/
unbox_mono_obj: typeof unbox_mono_obj;
// do we really want to advertize add these below ?
mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void;
mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void;
js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
js_to_mono_obj_root: typeof js_to_mono_obj_root;
conv_string_root: typeof conv_string_root;
unbox_mono_obj_root: typeof unbox_mono_obj_root;
mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
}
export type MONOType = {
mono_wasm_setenv: typeof mono_wasm_setenv;
mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
mono_wasm_load_config: typeof mono_wasm_load_config;
mono_load_runtime_and_bcl_args: typeof mono_load_runtime_and_bcl_args;
mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
mono_wasm_new_root: typeof mono_wasm_new_root;
mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
mono_wasm_release_roots: typeof mono_wasm_release_roots;
mono_run_main: typeof mono_run_main;
mono_run_main_and_exit: typeof mono_run_main_and_exit;
mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number;
mono_wasm_load_runtime: (unused: string, debug_level: number) => void;
config: MonoConfig | MonoConfigError;
loaded_files: string[];
setB32: typeof setB32;
setI8: typeof setI8;
setI16: typeof setI16;
setI32: typeof setI32;
setI52: typeof setI52;
setU52: typeof setU52;
setI64Big: typeof setI64Big;
setU8: typeof setU8;
setU16: typeof setU16;
setU32: typeof setU32;
setF32: typeof setF32;
setF64: typeof setF64;
getB32: typeof getB32;
getI8: typeof getI8;
getI16: typeof getI16;
getI32: typeof getI32;
getI52: typeof getI52;
getU52: typeof getU52;
getI64Big: typeof getI64Big;
getU8: typeof getU8;
getU16: typeof getU16;
getU32: typeof getU32;
getF32: typeof getF32;
getF64: typeof getF64;
diagnostics: Diagnostics;
}

View File

@ -75,7 +75,7 @@ export function mono_bind_assembly_entry_point(assembly: string, signature?: str
throw new Error("Could not find assembly: " + assembly);
let auto_set_breakpoint = 0;
if (runtimeHelpers.wait_for_debugger == 1)
if (runtimeHelpers.waitForDebugger == 1)
auto_set_breakpoint = 1;
const method = cwraps.mono_wasm_assembly_get_entry_point(asm, auto_set_breakpoint);

View File

@ -120,7 +120,7 @@ export function init_polyfills(replacements: EarlyReplacements): void {
}
// require replacement
const imports = anyModule.imports = Module.imports || <DotnetModuleConfigImports>{};
const imports = anyModule.imports = (Module.imports || {}) as DotnetModuleConfigImports;
const requireWrapper = (wrappedRequire: Function) => (name: string) => {
const resolved = (<any>Module.imports)[name];
if (resolved) {

View File

@ -6,35 +6,35 @@ import { AOTProfilerOptions, CoverageProfilerOptions } from "./types";
// Initialize the AOT profiler with OPTIONS.
// Requires the AOT profiler to be linked into the app.
// options = { write_at: "<METHODNAME>", send_to: "<METHODNAME>" }
// options = { writeAt: "<METHODNAME>", sendTo: "<METHODNAME>" }
// <METHODNAME> should be in the format <CLASS>::<METHODNAME>.
// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
// send_to defaults to 'WebAssembly.Runtime::DumpAotProfileData'.
// DumpAotProfileData stores the data into INTERNAL.aot_profile_data.
// writeAt defaults to 'WebAssembly.Runtime::StopProfile'.
// sendTo defaults to 'WebAssembly.Runtime::DumpAotProfileData'.
// DumpAotProfileData stores the data into INTERNAL.aotProfileData.
//
export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions): void {
if (options == null)
options = {};
if (!("write_at" in options))
options.write_at = "System.Runtime.InteropServices.JavaScript.JavaScriptExports::StopProfile";
if (!("send_to" in options))
options.send_to = "Interop/Runtime::DumpAotProfileData";
const arg = "aot:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
if (!("writeAt" in options))
options.writeAt = "System.Runtime.InteropServices.JavaScript.JavaScriptExports::StopProfile";
if (!("sendTo" in options))
options.sendTo = "Interop/Runtime::DumpAotProfileData";
const arg = "aot:write-at-method=" + options.writeAt + ",send-to-method=" + options.sendTo;
Module.ccall("mono_wasm_load_profiler_aot", null, ["string"], [arg]);
}
// options = { write_at: "<METHODNAME>", send_to: "<METHODNAME>" }
// options = { writeAt: "<METHODNAME>", sendTo: "<METHODNAME>" }
// <METHODNAME> should be in the format <CLASS>::<METHODNAME>.
// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
// send_to defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'.
// writeAt defaults to 'WebAssembly.Runtime::StopProfile'.
// sendTo defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'.
// DumpCoverageProfileData stores the data into INTERNAL.coverage_profile_data.
export function mono_wasm_init_coverage_profiler(options: CoverageProfilerOptions): void {
if (options == null)
options = {};
if (!("write_at" in options))
options.write_at = "WebAssembly.Runtime::StopProfile";
if (!("send_to" in options))
options.send_to = "WebAssembly.Runtime::DumpCoverageProfileData";
const arg = "coverage:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
if (!("writeAt" in options))
options.writeAt = "WebAssembly.Runtime::StopProfile";
if (!("sendTo" in options))
options.sendTo = "WebAssembly.Runtime::DumpCoverageProfileData";
const arg = "coverage:write-at-method=" + options.writeAt + ",send-to-method=" + options.sendTo;
Module.ccall("mono_wasm_load_profiler_coverage", null, ["string"], [arg]);
}

View File

@ -66,7 +66,6 @@ const inlineAssert = [
const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock }), typescript()];
const externalDependencies = [
"node/buffer"
];
const iffeConfig = {
@ -97,6 +96,19 @@ const typesConfig = {
external: externalDependencies,
plugins: [dts()],
};
const legacyConfig = {
input: "./net6-legacy/export-types.ts",
output: [
{
format: "es",
file: nativeBinDir + "/dotnet-legacy.d.ts",
banner: banner_dts,
plugins: [writeOnChangePlugin()],
}
],
external: externalDependencies,
plugins: [dts()],
};
let diagnosticMockTypesConfig = undefined;
@ -110,6 +122,12 @@ if (isDebug) {
banner: banner_dts,
plugins: [alwaysLF(), writeOnChangePlugin()],
});
legacyConfig.output.push({
format: "es",
file: "./dotnet-legacy.d.ts",
banner: banner_dts,
plugins: [alwaysLF(), writeOnChangePlugin()],
});
// export types into the source code and commit to git
diagnosticMockTypesConfig = {
@ -150,6 +168,7 @@ const workerConfigs = findWebWorkerInputs("./workers").map((workerInput) => make
const allConfigs = [
iffeConfig,
typesConfig,
legacyConfig,
].concat(workerConfigs)
.concat(diagnosticMockTypesConfig ? [diagnosticMockTypesConfig] : []);
export default defineConfig(allConfigs);

View File

@ -9,7 +9,7 @@ export async function mono_run_main_and_exit(main_assembly_name: string, args: s
set_exit_code(result);
} catch (error) {
if (error instanceof runtimeHelpers.ExitStatus) {
return;
return;// FIXME: should this be re-throw ?
}
set_exit_code(1, error);
}
@ -17,7 +17,7 @@ export async function mono_run_main_and_exit(main_assembly_name: string, args: s
export async function mono_run_main(main_assembly_name: string, args: string[]): Promise<number> {
mono_wasm_set_main_args(main_assembly_name, args);
if (runtimeHelpers.wait_for_debugger == -1) {
if (runtimeHelpers.waitForDebugger == -1) {
console.log("MONO_WASM: waiting for debugger...");
return await mono_wasm_wait_for_debugger().then(() => mono_call_assembly_entry_point(main_assembly_name, [args], "m"));
}

View File

@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import { mono_assert, CharPtrNull, DotnetModule, MonoConfig, wasm_type_symbol, MonoObject, MonoConfigError, LoadingResource, AssetEntry, ResourceRequest, DotnetPublicAPI } from "./types";
import { mono_assert, CharPtrNull, DotnetModule, MonoConfig, wasm_type_symbol, MonoObject, MonoConfigError, LoadingResource, AssetEntry, ResourceRequest } from "./types";
import { BINDING, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, Module, MONO, runtimeHelpers } from "./imports";
import cwraps, { init_c_exports } from "./cwraps";
import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
@ -19,13 +19,13 @@ import { init_polyfills_async } from "./polyfills";
import * as pthreads_worker from "./pthreads/worker";
import { createPromiseController, PromiseAndController } from "./promise-controller";
import { string_decoder } from "./strings";
import { mono_wasm_init_diagnostics } from "./diagnostics/index";
import { delay } from "./promise-utils";
import { init_managed_exports } from "./managed-exports";
import { init_legacy_exports } from "./net6-legacy/corebindings";
import { mono_wasm_load_bytes_into_heap } from "./memory";
import { cwraps_internal } from "./exports-internal";
import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy";
import { DotnetPublicAPI } from "./exports";
let all_assets_loaded_in_memory: Promise<void> | null = null;
const loaded_files: { url: string, file: string }[] = [];
@ -99,8 +99,7 @@ function instantiateWasm(
} else {
config = runtimeHelpers.config = Module.config = {} as any;
}
runtimeHelpers.diagnostic_tracing = !!config.diagnostic_tracing;
runtimeHelpers.enable_debugging = config.enable_debugging ? config.enable_debugging : 0;
runtimeHelpers.diagnosticTracing = !!config.diagnosticTracing;
if (!config.assets) {
config.assets = [];
}
@ -115,7 +114,7 @@ function instantiateWasm(
wasm_module_imports = imports;
wasm_success_callback = successCallback;
_instantiate_wasm_module();
instantiate_wasm_module();
return []; // No exports
}
@ -123,7 +122,7 @@ function preInit(isCustomStartup: boolean, userPreInit: (() => void)[]) {
Module.addRunDependency("mono_pre_init");
try {
mono_wasm_pre_init_essential();
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: preInit");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: preInit");
beforePreInit.promise_control.resolve();
// all user Module.preInit callbacks
userPreInit.forEach(fn => fn());
@ -158,7 +157,7 @@ async function preRunAsync(userPreRun: (() => void)[]) {
// wait for previous stages
await afterInstantiateWasm.promise;
await afterPreInit.promise;
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: preRunAsync");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: preRunAsync");
try {
// all user Module.preRun callbacks
userPreRun.map(fn => fn());
@ -175,7 +174,7 @@ async function preRunAsync(userPreRun: (() => void)[]) {
async function onRuntimeInitializedAsync(isCustomStartup: boolean, userOnRuntimeInitialized: () => void) {
// wait for previous stage
await afterPreRun.promise;
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: onRuntimeInitialized");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: onRuntimeInitialized");
// signal this stage, this will allow pending assets to allocate memory
beforeOnRuntimeInitialized.promise_control.resolve();
try {
@ -185,7 +184,7 @@ async function onRuntimeInitializedAsync(isCustomStartup: boolean, userOnRuntime
const expected_asset_count = config.assets ? config.assets.length : 0;
mono_assert(downloded_assets_count == expected_asset_count, "Expected assets to be downloaded");
mono_assert(instantiated_assets_count == expected_asset_count, "Expected assets to be in memory");
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: all assets are loaded in wasm memory");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: all assets are loaded in wasm memory");
// load runtime
await mono_wasm_before_user_runtime_initialized();
@ -212,7 +211,7 @@ async function onRuntimeInitializedAsync(isCustomStartup: boolean, userOnRuntime
async function postRunAsync(userpostRun: (() => void)[]) {
// wait for previous stage
await afterOnRuntimeInitialized.promise;
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: postRunAsync");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: postRunAsync");
try {
// all user Module.postRun callbacks
userpostRun.map(fn => fn());
@ -227,7 +226,7 @@ async function postRunAsync(userpostRun: (() => void)[]) {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function abort_startup(reason: any, should_exit: boolean): void {
if (runtimeHelpers.diagnostic_tracing) console.trace("MONO_WASM: abort_startup");
if (runtimeHelpers.diagnosticTracing) console.trace("MONO_WASM: abort_startup");
afterInstantiateWasm.promise_control.reject(reason);
beforePreInit.promise_control.reject(reason);
afterPreInit.promise_control.reject(reason);
@ -243,7 +242,7 @@ export function abort_startup(reason: any, should_exit: boolean): void {
// runs in both blazor and non-blazor
function mono_wasm_pre_init_essential(): void {
Module.addRunDependency("mono_wasm_pre_init_essential");
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential");
// init_polyfills() is already called from export.ts
init_crypto();
@ -257,7 +256,7 @@ function mono_wasm_pre_init_essential(): void {
// runs in both blazor and non-blazor
async function mono_wasm_pre_init_essential_async(): Promise<void> {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential_async");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential_async");
Module.addRunDependency("mono_wasm_pre_init_essential_async");
await init_polyfills_async();
@ -267,7 +266,7 @@ async function mono_wasm_pre_init_essential_async(): Promise<void> {
// runs just in non-blazor
async function mono_wasm_pre_init_full(): Promise<void> {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_pre_init_full");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_full");
Module.addRunDependency("mono_wasm_pre_init_full");
if (Module.configSrc) {
@ -280,9 +279,9 @@ async function mono_wasm_pre_init_full(): Promise<void> {
// runs just in non-blazor
async function mono_wasm_before_user_runtime_initialized(): Promise<void> {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_before_user_runtime_initialized");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_before_user_runtime_initialized");
if (!Module.config || Module.config.isError) {
if (!Module.config) {
return;
}
@ -295,7 +294,7 @@ async function mono_wasm_before_user_runtime_initialized(): Promise<void> {
await _apply_configuration_from_args();
mono_wasm_globalization_init();
if (!runtimeHelpers.mono_wasm_load_runtime_done) mono_wasm_load_runtime("unused", config.debug_level || 0);
if (!runtimeHelpers.mono_wasm_load_runtime_done) mono_wasm_load_runtime("unused", config.debugLevel || 0);
if (!runtimeHelpers.mono_wasm_runtime_is_ready) mono_wasm_runtime_ready();
setTimeout(() => {
// when there are free CPU cycles
@ -309,7 +308,7 @@ async function mono_wasm_before_user_runtime_initialized(): Promise<void> {
// runs in both blazor and non-blazor
async function mono_wasm_after_user_runtime_initialized(): Promise<void> {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized");
try {
if (!Module.disableDotnet6Compatibility && Module.exports) {
// Export emscripten defined in module through EXPORTED_RUNTIME_METHODS
@ -329,7 +328,7 @@ async function mono_wasm_after_user_runtime_initialized(): Promise<void> {
}
}
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: Initializing mono runtime");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: Initializing mono runtime");
if (Module.onDotnetReady) {
try {
@ -363,14 +362,14 @@ export function mono_wasm_setenv(name: string, value: string): void {
export function mono_wasm_set_runtime_options(options: string[]): void {
if (!Array.isArray(options))
throw new Error("Expected runtime_options to be an array of strings");
throw new Error("Expected runtimeOptions to be an array of strings");
const argv = Module._malloc(options.length * 4);
let aindex = 0;
for (let i = 0; i < options.length; ++i) {
const option = options[i];
if (typeof (option) !== "string")
throw new Error("Expected runtime_options to be an array of strings");
throw new Error("Expected runtimeOptions to be an array of strings");
Module.setValue(<any>argv + (aindex * 4), cwraps.mono_wasm_strdup(option), "i32");
aindex += 1;
}
@ -378,14 +377,14 @@ export function mono_wasm_set_runtime_options(options: string[]): void {
}
async function _instantiate_wasm_module(): Promise<void> {
async function instantiate_wasm_module(): Promise<void> {
// this is called so early that even Module exports like addRunDependency don't exist yet
try {
if (!config.assets && Module.configSrc) {
// when we are starting with mono-config,json, it could have dotnet.wasm location in it, we have to wait for it
await mono_wasm_load_config(Module.configSrc);
}
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: instantiateWasm");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: instantiate_wasm_module");
let assetToLoad: AssetEntry = {
name: "dotnet.wasm",
behavior: "dotnetwasm"
@ -399,7 +398,7 @@ async function _instantiate_wasm_module(): Promise<void> {
const pendingAsset = await start_asset_download(assetToLoad);
await beforePreInit.promise;
Module.addRunDependency("_instantiate_wasm_module");
Module.addRunDependency("instantiate_wasm_module");
mono_assert(pendingAsset && pendingAsset.pending, () => `Can't load ${assetToLoad.name}`);
const response = await pendingAsset.pending.response;
@ -407,20 +406,20 @@ async function _instantiate_wasm_module(): Promise<void> {
let compiledInstance: WebAssembly.Instance;
let compiledModule: WebAssembly.Module;
if (typeof WebAssembly.instantiateStreaming === "function" && contentType === "application/wasm") {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized streaming");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: instantiate_wasm_module streaming");
const streamingResult = await WebAssembly.instantiateStreaming(response, wasm_module_imports!);
compiledInstance = streamingResult.instance;
compiledModule = streamingResult.module;
} else {
const arrayBuffer = await response.arrayBuffer();
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized streaming");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: instantiate_wasm_module buffered");
const arrayBufferResult = await WebAssembly.instantiate(arrayBuffer, wasm_module_imports!);
compiledInstance = arrayBufferResult.instance;
compiledModule = arrayBufferResult.module;
}
++instantiated_assets_count;
wasm_success_callback!(compiledInstance, compiledModule);
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: instantiateWasm done");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: instantiate_wasm_module done");
afterInstantiateWasm.promise_control.resolve();
wasm_success_callback = null;
wasm_module_imports = null;
@ -429,16 +428,16 @@ async function _instantiate_wasm_module(): Promise<void> {
abort_startup(err, true);
throw err;
}
Module.removeRunDependency("_instantiate_wasm_module");
Module.removeRunDependency("instantiate_wasm_module");
}
// this need to be run only after onRuntimeInitialized event, when the memory is ready
function _instantiate_asset(asset: AssetEntry, url: string, bytes: Uint8Array) {
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: Loaded:${asset.name} as ${asset.behavior} size ${bytes.length} from ${url}`);
const virtualName: string = typeof (asset.virtual_path) === "string"
? asset.virtual_path
const virtualName: string = typeof (asset.virtualPath) === "string"
? asset.virtualPath
: asset.name;
let offset: VoidPtr | null = null;
@ -466,7 +465,7 @@ function _instantiate_asset(asset: AssetEntry, url: string, bytes: Uint8Array) {
if (fileName.startsWith("/"))
fileName = fileName.substr(1);
if (parentDirectory) {
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: Creating directory '${parentDirectory}'`);
Module.FS_createPath(
@ -476,7 +475,7 @@ function _instantiate_asset(asset: AssetEntry, url: string, bytes: Uint8Array) {
parentDirectory = "/";
}
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: Creating file '${fileName}' in directory '${parentDirectory}'`);
if (!mono_wasm_load_data_archive(bytes, parentDirectory)) {
@ -518,43 +517,41 @@ async function _apply_configuration_from_args() {
mono_wasm_setenv("TZ", "UTC");
}
for (const k in config.environment_variables) {
const v = config.environment_variables![k];
for (const k in config.environmentVariables) {
const v = config.environmentVariables![k];
if (typeof (v) === "string")
mono_wasm_setenv(k, v);
else
throw new Error(`Expected environment variable '${k}' to be a string but it was ${typeof v}: '${v}'`);
}
if (config.runtime_options)
mono_wasm_set_runtime_options(config.runtime_options);
if (config.runtimeOptions)
mono_wasm_set_runtime_options(config.runtimeOptions);
if (config.aot_profiler_options)
mono_wasm_init_aot_profiler(config.aot_profiler_options);
if (config.aotProfilerOptions)
mono_wasm_init_aot_profiler(config.aotProfilerOptions);
if (config.coverage_profiler_options)
mono_wasm_init_coverage_profiler(config.coverage_profiler_options);
if (config.coverageProfilerOptions)
mono_wasm_init_coverage_profiler(config.coverageProfilerOptions);
if (config.diagnostic_options) {
await mono_wasm_init_diagnostics(config.diagnostic_options);
}
// FIXME await mono_wasm_init_diagnostics(config.diagnosticOptions);
}
export function mono_wasm_load_runtime(unused?: string, debug_level?: number): void {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_load_runtime");
export function mono_wasm_load_runtime(unused?: string, debugLevel?: number): void {
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_load_runtime");
if (runtimeHelpers.mono_wasm_load_runtime_done) {
return;
}
runtimeHelpers.mono_wasm_load_runtime_done = true;
try {
if (debug_level == undefined) {
debug_level = 0;
if (config && config.debug_level) {
debug_level = 0 + debug_level;
if (debugLevel == undefined) {
debugLevel = 0;
if (config && config.debugLevel) {
debugLevel = 0 + debugLevel;
}
}
cwraps.mono_wasm_load_runtime(unused || "unused", debug_level);
runtimeHelpers.wait_for_debugger = config.wait_for_debugger;
cwraps.mono_wasm_load_runtime(unused || "unused", debugLevel);
runtimeHelpers.waitForDebugger = config.waitForDebugger;
if (!runtimeHelpers.mono_wasm_bindings_is_ready) bindings_init();
} catch (err: any) {
@ -570,7 +567,7 @@ export function mono_wasm_load_runtime(unused?: string, debug_level?: number): v
}
export function bindings_init(): void {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: bindings_init");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: bindings_init");
if (runtimeHelpers.mono_wasm_bindings_is_ready) {
return;
}
@ -610,7 +607,8 @@ export function bindings_init(): void {
function downloadResource(request: ResourceRequest): LoadingResource {
if (typeof Module.downloadResource === "function") {
return Module.downloadResource(request);
const loading = Module.downloadResource(request);
if (loading) return loading;
}
const options: any = {};
if (request.hash) {
@ -643,7 +641,7 @@ async function start_asset_download_sources(asset: AssetEntry): Promise<AssetEnt
return asset;
}
const sourcesList = asset.load_remote && config.remote_sources ? config.remote_sources : [""];
const sourcesList = asset.loadRemote && config.remoteSources ? config.remoteSources : [""];
let response: Response | undefined = undefined;
for (let sourcePrefix of sourcesList) {
sourcePrefix = sourcePrefix.trim();
@ -652,13 +650,14 @@ async function start_asset_download_sources(asset: AssetEntry): Promise<AssetEnt
sourcePrefix = "";
let attemptUrl;
const assemblyRootFolder = config.assemblyRootFolder;
if (!asset.resolvedUrl) {
if (sourcePrefix === "") {
if (asset.behavior === "assembly" || asset.behavior === "pdb")
attemptUrl = config.assembly_root + "/" + asset.name;
attemptUrl = assemblyRootFolder + "/" + asset.name;
else if (asset.behavior === "resource") {
const path = asset.culture !== "" ? `${asset.culture}/${asset.name}` : asset.name;
attemptUrl = config.assembly_root + "/" + path;
attemptUrl = assemblyRootFolder + "/" + path;
}
else
attemptUrl = asset.name;
@ -671,10 +670,10 @@ async function start_asset_download_sources(asset: AssetEntry): Promise<AssetEnt
attemptUrl = asset.resolvedUrl;
}
if (asset.name === attemptUrl) {
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: Attempting to download '${attemptUrl}'`);
} else {
if (runtimeHelpers.diagnostic_tracing)
if (runtimeHelpers.diagnosticTracing)
console.debug(`MONO_WASM: Attempting to download '${attemptUrl}' for ${asset.name}`);
}
try {
@ -707,15 +706,15 @@ async function start_asset_download_throttle(asset: AssetEntry): Promise<AssetEn
}
try {
++parallel_count;
if (parallel_count == runtimeHelpers.max_parallel_downloads) {
if (runtimeHelpers.diagnostic_tracing)
if (parallel_count == runtimeHelpers.maxParallelDownloads) {
if (runtimeHelpers.diagnosticTracing)
console.debug("MONO_WASM: Throttling further parallel downloads");
throttling = createPromiseController<void>();
}
return await start_asset_download_sources(asset);
}
catch (response: any) {
const isOkToFail = asset.is_optional || (asset.name.match(/\.pdb$/) && config.ignore_pdb_load_errors);
const isOkToFail = asset.isOptional || (asset.name.match(/\.pdb$/) && config.ignorePdbLoadErrors);
if (!isOkToFail) {
const err: any = new Error(`MONO_WASM: download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`);
err.status = response.status;
@ -724,8 +723,8 @@ async function start_asset_download_throttle(asset: AssetEntry): Promise<AssetEn
}
finally {
--parallel_count;
if (throttling && parallel_count == runtimeHelpers.max_parallel_downloads - 1) {
if (runtimeHelpers.diagnostic_tracing)
if (throttling && parallel_count == runtimeHelpers.maxParallelDownloads - 1) {
if (runtimeHelpers.diagnosticTracing)
console.debug("MONO_WASM: Resuming more parallel downloads");
const old_throttling = throttling;
throttling = undefined;
@ -755,8 +754,8 @@ async function start_asset_download(asset: AssetEntry): Promise<AssetEntry | und
const allDownloadsQueued = createPromiseController<void>();
async function mono_download_assets(): Promise<void> {
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_download_assets");
runtimeHelpers.max_parallel_downloads = runtimeHelpers.config.max_parallel_downloads || runtimeHelpers.max_parallel_downloads;
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_download_assets");
runtimeHelpers.maxParallelDownloads = runtimeHelpers.config.maxParallelDownloads || runtimeHelpers.maxParallelDownloads;
try {
const download_promises: Promise<AssetEntry | undefined>[] = [];
// start fetching and instantiating all assets in parallel
@ -862,7 +861,7 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi
if (configLoaded) {
return;
}
if (runtimeHelpers.diagnostic_tracing) console.debug("MONO_WASM: mono_wasm_load_config");
if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_load_config");
try {
const resolveSrc = runtimeHelpers.locateFile(configFilePath);
const configResponse = await runtimeHelpers.fetch_like(resolveSrc);
@ -872,15 +871,13 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi
config = runtimeHelpers.config = Module.config = Object.assign(Module.config as any, configData);
// normalize
config.environment_variables = config.environment_variables || {};
config.environmentVariables = config.environmentVariables || {};
config.assets = config.assets || [];
config.runtime_options = config.runtime_options || [];
config.globalization_mode = config.globalization_mode || "auto";
if (config.enable_debugging)
config.debug_level = config.enable_debugging;
config.runtimeOptions = config.runtimeOptions || [];
config.globalizationMode = config.globalizationMode || "auto";
if (typeof (config.environment_variables) !== "object")
throw new Error("Expected config.environment_variables to be unset or a dictionary-style object");
if (typeof (config.environmentVariables) !== "object")
throw new Error("Expected config.environmentVariables to be unset or a dictionary-style object");
if (Module.onConfigLoaded) {
try {
@ -891,8 +888,7 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi
throw err;
}
}
runtimeHelpers.diagnostic_tracing = !!runtimeHelpers.config.diagnostic_tracing;
runtimeHelpers.enable_debugging = runtimeHelpers.config.enable_debugging ? runtimeHelpers.config.enable_debugging : 0;
runtimeHelpers.diagnosticTracing = !!runtimeHelpers.config.diagnosticTracing;
configLoaded = true;
} catch (err) {
const errMessage = `Failed to load config file ${configFilePath} ${err}`;

View File

@ -3,6 +3,7 @@
"noImplicitAny": true,
"noEmitOnError": true,
"removeComments": false,
"module": "ES2020",
"sourceMap": false,
"target": "ES2018",
"moduleResolution": "Node",
@ -14,6 +15,7 @@
},
"exclude": [
"dotnet.d.ts",
"dotnet-legacy.d.ts",
"diagnostics-mock.d.ts",
"bin"
]

View File

@ -1,9 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import "node/buffer"; // we use the Buffer type to type some of Emscripten's APIs
import { JavaScriptExports } from "./managed-exports";
import { BINDINGType, MONOType } from "./net6-legacy/exports-legacy";
import { CharPtr, EmscriptenModule, ManagedPointer, NativePointer, VoidPtr, Int32Ptr } from "./types/emscripten";
export type GCHandle = {
@ -66,31 +63,27 @@ export function coerceNull<T extends ManagedPointer | NativePointer>(ptr: T | nu
}
export type MonoConfig = {
isError?: false,
assembly_root?: string, // the subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script.
assemblyRootFolder?: string, // the subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script.
assets?: AssetEntry[], // a list of assets to load along with the runtime. each asset is a dictionary-style Object with the following properties:
/**
* Either this or enable_debugging needs to be set
* debug_level > 0 enables debugging and sets the debug log level to debug_level
* debug_level == 0 disables debugging and enables interpreter optimizations
* debug_level < 0 enabled debugging and disables debug logging.
* debugLevel > 0 enables debugging and sets the debug log level to debugLevel
* debugLevel == 0 disables debugging and enables interpreter optimizations
* debugLevel < 0 enabled debugging and disables debug logging.
*/
debug_level?: number,
enable_debugging?: number, // Either this or debug_level needs to be set
globalization_mode?: GlobalizationMode, // configures the runtime's globalization mode
diagnostic_tracing?: boolean // enables diagnostic log messages during startup
remote_sources?: string[], // additional search locations for assets. Sources will be checked in sequential order until the asset is found. The string "./" indicates to load from the application directory (as with the files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates that asset loads can be attempted from a remote server. Sources must end with a "/".
max_parallel_downloads?: number, // we are throttling parallel downloads in order to avoid net::ERR_INSUFFICIENT_RESOURCES on chrome
environment_variables?: {
debugLevel?: number,
maxParallelDownloads?: number, // we are throttling parallel downloads in order to avoid net::ERR_INSUFFICIENT_RESOURCES on chrome
globalizationMode?: GlobalizationMode, // configures the runtime's globalization mode
diagnosticTracing?: boolean // enables diagnostic log messages during startup
remoteSources?: string[], // additional search locations for assets. Sources will be checked in sequential order until the asset is found. The string "./" indicates to load from the application directory (as with the files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates that asset loads can be attempted from a remote server. Sources must end with a "/".
environmentVariables?: {
[i: string]: string;
}, // dictionary-style Object containing environment variables
runtime_options?: string[], // array of runtime options as strings
aot_profiler_options?: AOTProfilerOptions, // dictionary-style Object. If omitted, aot profiler will not be initialized.
coverage_profiler_options?: CoverageProfilerOptions, // dictionary-style Object. If omitted, coverage profiler will not be initialized.
diagnostic_options?: DiagnosticOptions, // dictionary-style Object. If omitted, diagnostics will not be initialized.
ignore_pdb_load_errors?: boolean,
wait_for_debugger?: number
runtimeOptions?: string[], // array of runtime options as strings
aotProfilerOptions?: AOTProfilerOptions, // dictionary-style Object. If omitted, aot profiler will not be initialized.
coverageProfilerOptions?: CoverageProfilerOptions, // dictionary-style Object. If omitted, coverage profiler will not be initialized.
ignorePdbLoadErrors?: boolean,
waitForDebugger?: number
};
export type MonoConfigError = {
@ -108,10 +101,10 @@ export interface ResourceRequest {
// Types of assets that can be in the mono-config.js/mono-config.json file (taken from /src/tasks/WasmAppBuilder/WasmAppBuilder.cs)
export interface AssetEntry extends ResourceRequest {
virtual_path?: string, // if specified, overrides the path of the asset in the virtual filesystem and similar data structures once loaded.
virtualPath?: string, // if specified, overrides the path of the asset in the virtual filesystem and similar data structures once loaded.
culture?: string,
load_remote?: boolean, // if true, an attempt will be made to load the asset from each location in @args.remote_sources.
is_optional?: boolean // if true, any failure to load this asset will be ignored.
loadRemote?: boolean, // if true, an attempt will be made to load the asset from each location in @args.remoteSources.
isOptional?: boolean // if true, any failure to load this asset will be ignored.
buffer?: ArrayBuffer // if provided, we don't have to fetch it
pending?: LoadingResource // if provided, we don't have to start fetching it
}
@ -155,11 +148,10 @@ export type RuntimeHelpers = {
mono_wasm_bindings_is_ready: boolean;
loaded_files: string[];
max_parallel_downloads: number;
maxParallelDownloads: number;
config: MonoConfig;
diagnostic_tracing: boolean;
enable_debugging: number;
wait_for_debugger?: number;
diagnosticTracing: boolean;
waitForDebugger?: number;
fetch_like: (url: string, init?: RequestInit) => Promise<Response>;
scriptDirectory?: string
requirePromise: Promise<Function>
@ -178,13 +170,13 @@ export type GlobalizationMode =
export type AOTProfilerOptions = {
write_at?: string, // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::StopProfile'
send_to?: string // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::DumpAotProfileData' (DumpAotProfileData stores the data into INTERNAL.aot_profile_data.)
writeAt?: string, // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::StopProfile'
sendTo?: string // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::DumpAotProfileData' (DumpAotProfileData stores the data into INTERNAL.aotProfileData.)
}
export type CoverageProfilerOptions = {
write_at?: string, // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::StopProfile'
send_to?: string // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::DumpCoverageProfileData' (DumpCoverageProfileData stores the data into INTERNAL.coverage_profile_data.)
writeAt?: string, // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::StopProfile'
sendTo?: string // should be in the format <CLASS>::<METHODNAME>, default: 'WebAssembly.Runtime::DumpCoverageProfileData' (DumpCoverageProfileData stores the data into INTERNAL.coverage_profile_data.)
}
/// Options to configure EventPipe sessions that will be created and started at runtime startup
@ -208,7 +200,7 @@ export interface EventPipeSessionOptions {
/// Options to configure the diagnostic server
export type DiagnosticServerOptions = {
connect_url: string, // websocket URL to connect to.
connectUrl: string, // websocket URL to connect to.
suspend: string | boolean, // if true, the server will suspend the app when it starts until a diagnostic tool tells the runtime to resume.
}
// how we extended emscripten Module
@ -222,9 +214,9 @@ export type DotnetModuleConfig = {
onConfigLoaded?: (config: MonoConfig) => void | Promise<void>;
onDotnetReady?: () => void | Promise<void>;
imports?: DotnetModuleConfigImports;
imports?: any;
exports?: string[];
downloadResource?: (request: ResourceRequest) => LoadingResource
downloadResource?: (request: ResourceRequest) => LoadingResource | undefined
} & Partial<EmscriptenModule>
export type DotnetModuleConfigImports = {
@ -331,8 +323,7 @@ export type EarlyExports = {
binding: any,
internal: any,
module: any,
marshaled_exports: any,
marshaled_imports: any
marshaled_imports: any,
};
export type EarlyReplacements = {
fetch: any,
@ -369,18 +360,36 @@ export function notThenable<T>(x: T | PromiseLike<T>): x is T {
/// Primarily intended for debugging purposes.
export type EventPipeSessionID = bigint;
// 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 DotnetPublicAPI {
MONO: MONOType,
BINDING: BINDINGType,
INTERNAL: any,
EXPORTS: any,
IMPORTS: any,
Module: EmscriptenModule,
RuntimeId: number,
RuntimeBuildInfo: {
ProductVersion: string,
Configuration: string,
}
// in all the exported internals methods, we use the same data structures for stack frame as normal full blow interop
// see src\libraries\System.Runtime.InteropServices.JavaScript\src\System\Runtime\InteropServices\JavaScript\Interop\JavaScriptExports.cs
export interface JavaScriptExports {
// the marshaled signature is: void ReleaseJSOwnedObjectByGCHandle(GCHandle gcHandle)
_release_js_owned_object_by_gc_handle(gc_handle: GCHandle): void;
// the marshaled signature is: GCHandle CreateTaskCallback()
_create_task_callback(): GCHandle;
// the marshaled signature is: void CompleteTask<T>(GCHandle holder, Exception? exceptionResult, T? result)
_complete_task(holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs): void;
// the marshaled signature is: TRes? CallDelegate<T1,T2,T3TRes>(GCHandle callback, T1? arg1, T2? arg2, T3? arg3)
_call_delegate(callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any,
res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs): any;
}
export type MarshalerToJs = (arg: JSMarshalerArgument, sig?: JSMarshalerType, res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs) => any;
export type MarshalerToCs = (arg: JSMarshalerArgument, value: any, sig?: JSMarshalerType, res_converter?: MarshalerToCs, arg1_converter?: MarshalerToJs, arg2_converter?: MarshalerToJs) => void;
export interface JSMarshalerArguments extends NativePointer {
__brand: "JSMarshalerArguments"
}
export interface JSFunctionSignature extends NativePointer {
__brand: "JSFunctionSignatures"
}
export interface JSMarshalerType extends NativePointer {
__brand: "JSMarshalerType"
}
export interface JSMarshalerArgument extends NativePointer {
__brand: "JSMarshalerArgument"
}

View File

@ -59,10 +59,10 @@ export declare interface EmscriptenModule {
ready: Promise<unknown>;
instantiateWasm?: (imports: WebAssembly.Imports, successCallback: (instance: WebAssembly.Instance, module: WebAssembly.Module) => void) => any;
preInit?: (() => any)[];
preRun?: (() => any)[];
preInit?: (() => any)[] | (() => any);
preRun?: (() => any)[] | (() => any);
onRuntimeInitialized?: () => any;
postRun?: (() => any)[];
postRun?: (() => any)[] | (() => any);
onAbort?: { (error: any): void };
}

View File

@ -1,3 +1,4 @@
// only when script loaded as CJS
declare const __filename: string;
declare const __dirname: string;
declare type Buffer = {}

View File

@ -5,9 +5,9 @@ import { prevent_timer_throttling } from "./scheduling";
import { Queue } from "./queue";
import { PromiseController, createPromiseController } from "./promise-controller";
import { mono_assert } from "./types";
import { VoidPtr } from "./export-types";
import { Module } from "./imports";
import { setI32 } from "./memory";
import { VoidPtr } from "./types/emscripten";
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");

View File

@ -13,6 +13,6 @@ public partial class MyClass
return text;
}
[JSImport("window.location.href")]
[JSImport("window.location.href", "main.js")]
internal static partial string GetHRef();
}

View File

@ -55,6 +55,9 @@ function set_exit_code(exit_code, reason) {
console.error(reason);
else
console.error(JSON.stringify(reason));
if (is_browser && document.getElementById("out"))
document.getElementById("out").innerHTML = `error: ${reason}`;
}
if (runArgs && runArgs.forwardConsole) {
@ -79,8 +82,8 @@ function stringify_as_error_with_stack(err) {
return "";
// FIXME:
if (App && App.INTERNAL)
return App.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (App && App.runtime && App.runtime.INTERNAL)
return App.runtime.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (err.stack)
return err.stack;
@ -142,7 +145,8 @@ function applyArguments() {
}
}
try {
App.run = async function run(main) {
try {
const argsResponse = await fetch('./runArgs.json')
if (!argsResponse.ok) {
console.debug(`could not load ./runArgs.json: ${argsResponse.status}. Ignoring`);
@ -153,26 +157,26 @@ try {
initRunArgs();
applyArguments();
createDotnetRuntime(({ MONO, INTERNAL, BINDING, IMPORTS, Module }) => ({
const runtime = await createDotnetRuntime(({ Module, INTERNAL }) => ({
disableDotnet6Compatibility: true,
config: null,
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
if (!Module.config) {
if (!config) {
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 runArgs.environmentVariables) {
config.environment_variables[variable] = runArgs.environmentVariables[variable];
config.environmentVariables[variable] = runArgs.environmentVariables[variable];
}
config.diagnostic_tracing = !!runArgs.diagnosticTracing;
config.diagnosticTracing = !!runArgs.diagnosticTracing;
if (!!runArgs.debugging) {
if (config.debug_level == 0)
config.debug_level = -1;
if (config.debugLevel == 0)
config.debugLevel = -1;
config.wait_for_debugger = -1;
config.waitForDebugger = -1;
}
},
onDotnetReady: async () => {
@ -186,10 +190,14 @@ try {
if (runArgs.runtimeArgs.length > 0)
INTERNAL.mono_wasm_set_runtime_options(runArgs.runtimeArgs);
Object.assign(App, { MONO, BINDING, IMPORTS, Module, runArgs });
try {
},
onAbort: (error) => {
set_exit_code(1, error);
},
}));
App.runtime = runtime;
App.runArgs = runArgs;
App.main = main;
if (App.main) {
let exit_code = await App.main(runArgs.applicationArguments);
set_exit_code(exit_code ?? 0);
@ -197,18 +205,8 @@ try {
else {
set_exit_code(1, "WASM ERROR: no App.main defined");
}
} catch (err) {
if (is_browser && document.getElementById("out"))
document.getElementById("out").innerHTML = `error: ${err}`;
set_exit_code(1, err);
}
},
onAbort: (error) => {
set_exit_code(1, error);
},
}));
}
catch (err) {
catch (err) {
set_exit_code(2, err);
}
}

View File

@ -1,15 +1,18 @@
import { App } from './app-support.js'
App.main = async function (applicationArguments) {
App.IMPORTS.window = {
async function main(applicationArguments) {
App.runtime.setModuleImports("main.js", {
window: {
location: {
href: () => globalThis.window.location.href
}
};
const exports = await App.MONO.mono_wasm_get_assembly_exports("browser.0.dll");
}
});
const exports = await App.runtime.getAssemblyExports("browser.0.dll");
const text = exports.MyClass.Greeting();
document.getElementById("out").innerHTML = `${text}`;
await App.MONO.mono_run_main("browser.0.dll", applicationArguments);
await App.runtime.runMain("browser.0.dll", applicationArguments);
}
App.run(main);

View File

@ -14,6 +14,6 @@ public partial class MyClass
return text;
}
[JSImport("node.process.version")]
[JSImport("node.process.version", "main.mjs")]
internal static partial string GetNodeVersion();
}

View File

@ -24,8 +24,8 @@ function stringify_as_error_with_stack(err) {
return "";
// FIXME:
if (App && App.INTERNAL)
return App.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (App && App.runtime.INTERNAL)
return App.runtime.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (err.stack)
return err.stack;
@ -46,7 +46,7 @@ function set_exit_code(exit_code, reason) {
console.error(JSON.stringify(reason));
}
if (App && App.INTERNAL) {
if (App && App.runtime && App.runtime.INTERNAL) {
let _flush = function (_stream) {
return new Promise((resolve, reject) => {
_stream.on('error', (error) => reject(error));
@ -58,10 +58,10 @@ function set_exit_code(exit_code, reason) {
Promise.all([stdoutFlushed, stderrFlushed])
.then(
() => App.INTERNAL.mono_wasm_exit(exit_code),
() => App.runtime.INTERNAL.mono_wasm_exit(exit_code),
reason => {
console.error(`flushing std* streams failed: ${reason}`);
App.INTERNAL.mono_wasm_exit(123456);
App.runtime.INTERNAL.mono_wasm_exit(123456);
});
}
}
@ -94,7 +94,7 @@ function mergeArguments() {
} else if (currentArg.startsWith("--runtime-arg=")) {
const arg = currentArg.substring("--runtime-arg=".length);
runArgs.runtimeArgs.push(arg);
} else if (currentArg == "--diagnostic_tracing") {
} else if (currentArg == "--diagnostic-tracing") {
runArgs.diagnosticTracing = true;
} else if (currentArg.startsWith("--working-dir=")) {
const arg = currentArg.substring("--working-dir=".length);
@ -111,8 +111,8 @@ function mergeArguments() {
is_debugging = runArgs.debugging === true;
}
try {
App.run = async function run(main) {
try {
try {
if (await stat('./runArgs.json')) {
const argsJson = await readFile('./runArgs.json', { encoding: "utf8" });
@ -125,26 +125,26 @@ try {
initRunArgs();
mergeArguments();
createDotnetRuntime(({ MONO, INTERNAL, BINDING, IMPORTS, Module }) => ({
const runtime = await createDotnetRuntime(({ Module, INTERNAL }) => ({
disableDotnet6Compatibility: true,
config: null,
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
if (!Module.config) {
if (!config) {
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 runArgs.environmentVariables) {
config.environment_variables[variable] = runArgs.environmentVariables[variable];
config.environmentVariables[variable] = runArgs.environmentVariables[variable];
}
config.diagnostic_tracing = !!runArgs.diagnosticTracing;
config.diagnosticTracing = !!runArgs.diagnosticTracing;
if (is_debugging) {
if (config.debug_level == 0)
config.debug_level = -1;
if (config.debugLevel == 0)
config.debugLevel = -1;
config.wait_for_debugger = -1;
config.waitForDebugger = -1;
}
},
onDotnetReady: async () => {
@ -159,9 +159,15 @@ try {
if (runArgs.runtimeArgs.length > 0)
INTERNAL.mono_wasm_set_runtime_options(runArgs.runtimeArgs);
Object.assign(App, { MONO, INTERNAL, BINDING, IMPORTS, Module, runArgs });
},
onAbort: (error) => {
set_exit_code(1, error);
},
}));
App.runtime = runtime;
App.runArgs = runArgs;
App.main = main;
try {
if (App.main) {
let exit_code = await App.main(runArgs.applicationArguments);
set_exit_code(exit_code ?? 0);
@ -169,17 +175,8 @@ try {
else {
set_exit_code(1, "WASM ERROR: no App.main defined");
}
} catch (err) {
if (is_browser && document.getElementById("out"))
document.getElementById("out").innerHTML = `error: ${err}`;
set_exit_code(1, err);
}
},
onAbort: (error) => {
set_exit_code(1, error);
},
}));
}
catch (err) {
catch (err) {
set_exit_code(2, err);
}
}

View File

@ -1,16 +1,19 @@
import { App } from './app-support.mjs'
App.main = async function (applicationArguments) {
App.IMPORTS.node = {
process : {
async function main(applicationArguments) {
App.runtime.setModuleImports("main.mjs", {
node: {
process: {
version: () => globalThis.process.version
}
};
}
});
const exports = await App.MONO.mono_wasm_get_assembly_exports("console.0.dll");
const exports = await App.runtime.getAssemblyExports("console.0.dll");
const text = exports.MyClass.Greeting();
console.log(text);
return await App.MONO.mono_run_main("console.0.dll", applicationArguments);
return await App.runtime.runMain("console.0.dll", applicationArguments);
}
App.run(main);

View File

@ -84,9 +84,9 @@ function set_exit_code(exit_code, reason) {
}
if (is_browser) {
if (App.Module) {
if (App.runtime && App.runtime.Module) {
// Notify the selenium script
App.Module.exit_code = exit_code;
App.runtime.Module.exit_code = exit_code;
}
//Tell xharness WasmBrowserTestRunner what was the exit code
@ -112,7 +112,7 @@ function set_exit_code(exit_code, reason) {
console.log("WASM EXIT " + exit_code);
}
} else if (App && App.INTERNAL) {
} else if (App && App.runtime && App.runtime.INTERNAL) {
if (is_node) {
// NodeJS is lazy with flushing of console stream.
// We need all of the output, so we force it to flush.
@ -128,13 +128,13 @@ function set_exit_code(exit_code, reason) {
Promise.all([stdoutFlushed, stderrFlushed])
.then(
() => App.INTERNAL.mono_wasm_exit(exit_code),
() => App.runtime.INTERNAL.mono_wasm_exit(exit_code),
reason => {
console.error(`flushing std* streams failed: ${reason}`);
App.INTERNAL.mono_wasm_exit(123456);
App.runtime.INTERNAL.mono_wasm_exit(123456);
});
} else {
App.INTERNAL.mono_wasm_exit(exit_code);
App.runtime.INTERNAL.mono_wasm_exit(exit_code);
}
}
}
@ -144,8 +144,8 @@ function stringify_as_error_with_stack(err) {
return "";
// FIXME:
if (App && App.INTERNAL)
return App.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (App && App.runtime && App.runtime.INTERNAL)
return App.runtime.INTERNAL.mono_wasm_stringify_as_error_with_stack(err);
if (err.stack)
return err.stack;
@ -191,7 +191,7 @@ function processQueryArguments(incomingArguments) {
runArgs.runtimeArgs.push(arg);
} else if (currentArg == "--disable-on-demand-gc") {
runArgs.enableGC = false;
} else if (currentArg == "--diagnostic_tracing") {
} else if (currentArg == "--diagnostic-tracing") {
runArgs.diagnosticTracing = true;
} else if (currentArg.startsWith("--working-dir=")) {
const arg = currentArg.substring("--working-dir=".length);
@ -340,29 +340,30 @@ if (typeof globalThis.crypto === 'undefined') {
}
}
Promise.all([argsPromise, loadDotnetPromise]).then(async ([_, createDotnetRuntime]) => {
Promise.all([argsPromise, loadDotnetPromise]).then(async ([runArgs, createDotnetRuntime]) => {
applyArguments();
return createDotnetRuntime(({ MONO, INTERNAL, BINDING, IMPORTS, EXPORTS, Module }) => ({
const runtime = await createDotnetRuntime(({ INTERNAL, Module }) => {
return ({
disableDotnet6Compatibility: true,
config: null,
configSrc: runArgs.configSrc || "./mono-config.json",
onConfigLoaded: (config) => {
if (!Module.config) {
if (!config) {
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 runArgs.environmentVariables) {
config.environment_variables[variable] = runArgs.environmentVariables[variable];
config.environmentVariables[variable] = runArgs.environmentVariables[variable];
}
config.diagnostic_tracing = !!runArgs.diagnosticTracing;
config.diagnosticTracing = !!runArgs.diagnosticTracing;
if (!!runArgs.debugging) {
if (config.debug_level == 0)
config.debug_level = -1;
if (config.debugLevel == 0)
config.debugLevel = -1;
config.wait_for_debugger = -1;
config.waitForDebugger = -1;
}
if (is_node) {
@ -396,7 +397,7 @@ Promise.all([argsPromise, loadDotnetPromise]).then(async ([_, createDotnetRuntim
}
// Must be after loading npm modules.
config.environment_variables["IsWebSocketSupported"] = ("WebSocket" in globalThis).toString().toLowerCase();
config.environmentVariables["IsWebSocketSupported"] = ("WebSocket" in globalThis).toString().toLowerCase();
},
preRun: () => {
if (!runArgs.enableGC) {
@ -411,24 +412,26 @@ Promise.all([argsPromise, loadDotnetPromise]).then(async ([_, createDotnetRuntim
}
Module.FS.chdir(runArgs.workingDirectory);
App.init({ MONO, INTERNAL, BINDING, IMPORTS, EXPORTS, Module, runArgs });
},
onAbort: (error) => {
set_exit_code(1, stringify_as_error_with_stack(new Error()));
},
}));
})
});
App.runtime = runtime
App.runArgs = runArgs
App.init();
}).catch(function (err) {
set_exit_code(1, "failed to load the dotnet.js file.\n" + stringify_as_error_with_stack(err));
});
const App = {
init: async function ({ MONO, INTERNAL, BINDING, IMPORTS, EXPORTS, Module, runArgs }) {
Object.assign(App, { MONO, INTERNAL, BINDING, IMPORTS, EXPORTS, Module, runArgs });
init: async function () {
console.info("Initializing.....");
for (let i = 0; i < runArgs.profilers.length; ++i) {
const init = Module.cwrap('mono_wasm_load_profiler_' + runArgs.profilers[i], 'void', ['string']);
const init = App.runtime.Module.cwrap('mono_wasm_load_profiler_' + runArgs.profilers[i], 'void', ['string']);
init("");
}
@ -438,7 +441,7 @@ const App = {
}
if (runArgs.applicationArguments[0] == "--regression") {
const exec_regression = Module.cwrap('mono_wasm_exec_regression', 'number', ['number', 'string']);
const exec_regression = App.runtime.Module.cwrap('mono_wasm_exec_regression', 'number', ['number', 'string']);
let res = 0;
try {
@ -457,7 +460,7 @@ const App = {
}
if (runArgs.runtimeArgs.length > 0)
INTERNAL.mono_wasm_set_runtime_options(runArgs.runtimeArgs);
App.runtime.INTERNAL.mono_wasm_set_runtime_options(runArgs.runtimeArgs);
if (runArgs.applicationArguments[0] == "--run") {
// Run an exe
@ -468,7 +471,7 @@ const App = {
try {
const main_assembly_name = runArgs.applicationArguments[1];
const app_args = runArgs.applicationArguments.slice(2);
const result = await App.MONO.mono_run_main(main_assembly_name, app_args);
const result = await App.runtime.runMain(main_assembly_name, app_args);
set_exit_code(result);
} catch (error) {
if (error.name != "ExitStatus") {
@ -480,7 +483,7 @@ const App = {
}
},
/** Runs a particular test
/** Runs a particular test in legacy interop tests
* @type {(method_name: string, args: any[]=, signature: any=) => return number}
*/
call_test_method: function (method_name, args, signature) {
@ -490,7 +493,7 @@ const App = {
const fqn = "[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name;
try {
const method = App.BINDING.bind_static_method(fqn, signature);
const method = App.runtime.BINDING.bind_static_method(fqn, signature);
return method.apply(null, args || []);
} catch (exc) {
console.error("exception thrown in", fqn);
@ -504,16 +507,12 @@ const App = {
args.push("MONO");
args.push("BINDING");
args.push("INTERNAL");
args.push("IMPORTS");
args.push("EXPORTS");
const userFunction = new Function(...args, code);
return function (...args) {
args[arg_count + 0] = globalThis.App.MONO;
args[arg_count + 1] = globalThis.App.BINDING;
args[arg_count + 2] = globalThis.App.INTERNAL;
args[arg_count + 3] = globalThis.App.IMPORTS;
args[arg_count + 4] = globalThis.App.EXPORTS;
args[arg_count + 0] = globalThis.App.runtime.MONO;
args[arg_count + 1] = globalThis.App.runtime.BINDING;
args[arg_count + 2] = globalThis.App.runtime.INTERNAL;
return userFunction(...args);
};
},
@ -521,7 +520,7 @@ const App = {
const closedEval = function (Module, MONO, BINDING, INTERNAL, code) {
return eval(code);
};
const res = closedEval(globalThis.App.Module, globalThis.App.MONO, globalThis.App.BINDING, globalThis.App.INTERNAL, js_code);
const res = closedEval(globalThis.App.runtime.Module, globalThis.App.runtime.MONO, globalThis.App.runtime.BINDING, globalThis.App.runtime.INTERNAL, js_code);
return (res === undefined || res === null || typeof res === "string")
? null
: res.toString();

View File

@ -291,6 +291,7 @@
<Copy SourceFiles="$(NativeBinDir)dotnet.js;
$(NativeBinDir)dotnet.d.ts;
$(NativeBinDir)dotnet-legacy.d.ts;
$(NativeBinDir)package.json;
$(NativeBinDir)dotnet.wasm;
$(NativeBinDir)\src\dotnet-crypto-worker.js;
@ -338,7 +339,7 @@
<ItemGroup>
<_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/**/*.ts"
Exclude="$(MonoProjectRoot)wasm/runtime/dotnet.d.ts;$(MonoProjectRoot)wasm/runtime/diagnostics-mock.d.ts;$(MonoProjectRoot)wasm/runtime/node_modules/**/*.ts" />
Exclude="$(MonoProjectRoot)wasm/runtime/dotnet.d.ts;$(MonoProjectRoot)wasm/runtime/dotnet-legacy.d.ts;$(MonoProjectRoot)wasm/runtime/diagnostics-mock.d.ts;$(MonoProjectRoot)wasm/runtime/node_modules/**/*.ts" />
<_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/**/tsconfig.*"
Exclude="$(MonoProjectRoot)wasm/runtime/node_modules/**/tsconfig.*" />
<_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/workers/**/*.js"/>

View File

@ -54,7 +54,7 @@ public class WasmAppBuilder : Task
// - Value: can be a number, bool, quoted string, or json string
//
// Examples:
// <WasmExtraConfig Include="enable_profiler" Value="true" />
// <WasmExtraConfig Include="enableProfiler" Value="true" />
// <WasmExtraConfig Include="json" Value="{ &quot;abc&quot;: 4 }" />
// <WasmExtraConfig Include="string_val" Value="&quot;abc&quot;" />
// <WasmExtraConfig Include="string_with_json" Value="&quot;{ &quot;abc&quot;: 4 }&quot;" />
@ -73,13 +73,13 @@ public class WasmAppBuilder : Task
private sealed class WasmAppConfig
{
[JsonPropertyName("assembly_root")]
[JsonPropertyName("assemblyRootFolder")]
public string AssemblyRoot { get; set; } = "managed";
[JsonPropertyName("debug_level")]
[JsonPropertyName("debugLevel")]
public int DebugLevel { get; set; } = 0;
[JsonPropertyName("assets")]
public List<object> Assets { get; } = new List<object>();
[JsonPropertyName("remote_sources")]
[JsonPropertyName("remoteSources")]
public List<string> RemoteSources { get; set; } = new List<string>();
[JsonExtensionData]
public Dictionary<string, object?> Extra { get; set; } = new();
@ -117,14 +117,14 @@ public class WasmAppBuilder : Task
private sealed class VfsEntry : AssetEntry
{
public VfsEntry(string name) : base(name, "vfs") {}
[JsonPropertyName("virtual_path")]
[JsonPropertyName("virtualPath")]
public string? VirtualPath { get; set; }
}
private sealed class IcuData : AssetEntry
{
public IcuData(string name) : base(name, "icu") {}
[JsonPropertyName("load_remote")]
[JsonPropertyName("loadRemote")]
public bool LoadRemote { get; set; }
}

View File

@ -13,7 +13,7 @@ try {
const { BINDING } = await createDotnetRuntime(({ MONO }) => ({
configSrc: "./mono-config.json",
onConfigLoaded: () => {
MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
MONO.config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
},
}));
const testMeaning = BINDING.bind_static_method("[WebAssembly.Browser.HotReload.Test] Sample.Test:TestMeaning");