Skip to content

Commit 0d80733

Browse files
pavelsavaramarafradical
authored
[wasm] deprecate legacy JS API and propose new (dotnet#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>
1 parent 0ea3031 commit 0d80733

File tree

75 files changed

+1631
-1356
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1631
-1356
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-
7676
src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input.txt text eol=lf
7777
src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input-big.txt text eol=lf
7878
src/mono/wasm/runtime/dotnet.d.ts text eol=lf
79+
src/mono/wasm/runtime/dotnet-legacy.d.ts text eol=lf

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ node_modules/
188188
*.metaproj.tmp
189189
bin.localpkg/
190190
src/mono/wasm/runtime/dotnet.d.ts.sha256
191+
src/mono/wasm/runtime/dotnet-legacy.d.ts.sha256
192+
191193
src/mono/sample/wasm/browser-nextjs/public/
192194

193195
# RIA/Silverlight projects

eng/liveBuilds.targets

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@
181181
$(LibrariesNativeArtifactsPath)dotnet.js;
182182
$(LibrariesNativeArtifactsPath)src\dotnet-crypto-worker.js;
183183
$(LibrariesNativeArtifactsPath)dotnet.d.ts;
184+
$(LibrariesNativeArtifactsPath)dotnet-legacy.d.ts;
184185
$(LibrariesNativeArtifactsPath)package.json;
185186
$(LibrariesNativeArtifactsPath)dotnet.wasm;
186187
$(LibrariesNativeArtifactsPath)dotnet.js.symbols;

src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@
218218
<PlatformManifestFileEntry Include="dotnet.worker.js" IsNative="true" />
219219
<PlatformManifestFileEntry Include="dotnet.js.symbols" IsNative="true" />
220220
<PlatformManifestFileEntry Include="dotnet.d.ts" IsNative="true" />
221+
<PlatformManifestFileEntry Include="dotnet-legacy.d.ts" IsNative="true" />
221222
<PlatformManifestFileEntry Include="dotnet.wasm" IsNative="true" />
222223
<PlatformManifestFileEntry Include="dotnet.timezones.blat" IsNative="true" />
223224
<PlatformManifestFileEntry Include="icudt.dat" IsNative="true" />

src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public static unsafe void Int52TestOK(long value)
2626
long dummy = 0xA6A6A6A6L;
2727
long actual2 = dummy;
2828
var bagFn = new Function("ptr", "ptr2", @"
29-
const value=globalThis.App.MONO.getI52(ptr);
30-
globalThis.App.MONO.setI52(ptr2, value);
29+
const value=globalThis.App.runtime.getHeapI52(ptr);
30+
globalThis.App.runtime.setHeapI52(ptr2, value);
3131
return ''+value;");
3232

3333
uint ptr = (uint)Unsafe.AsPointer(ref expected);
@@ -53,8 +53,8 @@ public static unsafe void UInt52TestOK(ulong value)
5353
ulong dummy = 0xA6A6A6A6UL;
5454
ulong actual2 = dummy;
5555
var bagFn = new Function("ptr", "ptr2", @"
56-
const value=globalThis.App.MONO.getI52(ptr);
57-
globalThis.App.MONO.setU52(ptr2, value);
56+
const value=globalThis.App.runtime.getHeapI52(ptr);
57+
globalThis.App.runtime.setHeapU52(ptr2, value);
5858
return ''+value;");
5959

6060
uint ptr = (uint)Unsafe.AsPointer(ref expected);
@@ -99,14 +99,14 @@ public static unsafe void Int52TestRange(double value)
9999
long actual = 0;
100100
uint ptr = (uint)Unsafe.AsPointer(ref actual);
101101
var bagFn = new Function("ptr", "value", @"
102-
globalThis.App.MONO.setI52(ptr, value);");
102+
globalThis.App.runtime.setHeapI52(ptr, value);");
103103
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
104104
Assert.Contains("Value is not a safe integer", ex.Message);
105105

106106
double expectedD = value;
107107
uint ptrD = (uint)Unsafe.AsPointer(ref expectedD);
108108
var bagFnD = new Function("ptr", "value", @"
109-
globalThis.App.MONO.getI52(ptr);");
109+
globalThis.App.runtime.getHeapI52(ptr);");
110110
var exD = Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
111111
Assert.Contains("Value is not a safe integer", ex.Message);
112112
}
@@ -118,14 +118,14 @@ public static unsafe void UInt52TestRange(double value)
118118
long actual = 0;
119119
uint ptr = (uint)Unsafe.AsPointer(ref actual);
120120
var bagFn = new Function("ptr", "value", @"
121-
globalThis.App.MONO.setU52(ptr, value);");
121+
globalThis.App.runtime.setHeapU52(ptr, value);");
122122
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
123123
Assert.Contains("Can't convert negative Number into UInt64", ex.Message);
124124

125125
double expectedD = value;
126126
uint ptrD = (uint)Unsafe.AsPointer(ref expectedD);
127127
var bagFnD = new Function("ptr", "value", @"
128-
globalThis.App.MONO.getU52(ptr);");
128+
globalThis.App.runtime.getHeapU52(ptr);");
129129
var exD = Assert.Throws<JSException>(() => bagFn.Call(null, ptr, value));
130130
Assert.Contains("Can't convert negative Number into UInt64", ex.Message);
131131
}
@@ -136,7 +136,7 @@ public static unsafe void Int52TestNaN()
136136
long actual = 0;
137137
uint ptr = (uint)Unsafe.AsPointer(ref actual);
138138
var bagFn = new Function("ptr", "value", @"
139-
globalThis.App.MONO.setI52(ptr, value);");
139+
globalThis.App.runtime.setHeapI52(ptr, value);");
140140
var ex=Assert.Throws<JSException>(() => bagFn.Call(null, ptr, double.NaN));
141141
Assert.Contains("Value is not a safe integer: NaN (number)", ex.Message);
142142
}

src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public static void StopProfile()
117117
{
118118
}
119119

120-
// Called by the AOT profiler to save profile data into INTERNAL.aot_profile_data
120+
// Called by the AOT profiler to save profile data into INTERNAL.aotProfileData
121121
[MethodImpl(MethodImplOptions.NoInlining)] // https://github.com/dotnet/runtime/issues/71425
122122
public static unsafe void DumpAotProfileData(ref byte buf, int len, string extraArg)
123123
{
@@ -133,7 +133,7 @@ public static unsafe void DumpAotProfileData(ref byte buf, int len, string extra
133133
if (module == null)
134134
throw new InvalidOperationException();
135135

136-
module.SetProperty("aot_profile_data", span.ToArray());
136+
module.SetProperty("aotProfileData", span.ToArray());
137137
}
138138
}
139139
}

src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSImportAttribute.cs

+3-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ namespace System.Runtime.InteropServices.JavaScript
2020
/// public static partial int librarySum(int a, int b);
2121
/// [JSImport("Math.sum", "my-math-helper")]
2222
/// public static partial int libraryNamespaceSum(int a, int b);
23-
/// [JSImport("IMPORTS.sum")]
24-
/// public static partial int runtimeImportsSum(int a, int b);
2523
/// [JSImport("globalThis.Math.sum")]
2624
/// public static partial int globalSum(int a, int b);
2725
/// </code>
@@ -31,7 +29,7 @@ namespace System.Runtime.InteropServices.JavaScript
3129
public sealed class JSImportAttribute : Attribute
3230
{
3331
/// <summary>
34-
/// 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.
32+
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the module.
3533
/// Functions nested inside of objects can be referred to by using the dot operator to connect one or more names.
3634
/// </summary>
3735
public string FunctionName { get; }
@@ -44,7 +42,7 @@ public sealed class JSImportAttribute : Attribute
4442
/// <summary>
4543
/// Initializes a new instance of the <see cref="JSImportAttribute"/>.
4644
/// </summary>
47-
/// <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>
45+
/// <param name="functionName">Name of the function to be bound in the module. It allows dots for nested objects.</param>
4846
public JSImportAttribute(string functionName)
4947
{
5048
FunctionName = functionName;
@@ -54,7 +52,7 @@ public JSImportAttribute(string functionName)
5452
/// Initializes a new instance of the <see cref="JSImportAttribute"/>.
5553
/// </summary>
5654
/// <param name="functionName">
57-
/// 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.
55+
/// The name of the target JavaScript function. This name will be used as a key to locate the function in the module.
5856
/// Functions nested inside of objects can be referred to by using the dot operator to connect one or more names.
5957
/// </param>
6058
/// <param name="moduleName">

src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTestHelper.cs

+4
Original file line numberDiff line numberDiff line change
@@ -918,13 +918,17 @@ public static JSObject EchoIJSObject([JSMarshalAs<JSType.Object>] JSObject arg1)
918918
}
919919
#endregion JSObject
920920

921+
[JSImport("setup", "JavaScriptTestHelper")]
922+
internal static partial Task Setup();
923+
921924
static JSObject _module;
922925
public static async Task InitializeAsync()
923926
{
924927
if (_module == null)
925928
{
926929
// Log("JavaScriptTestHelper.mjs importing");
927930
_module = await JSHost.ImportAsync("JavaScriptTestHelper", "./JavaScriptTestHelper.mjs");
931+
await Setup();
928932
// Log("JavaScriptTestHelper.mjs imported");
929933
}
930934
}

src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTestHelper.mjs

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ class JSData {
55
constructor(name) {
66
this.name = name;
77
}
8-
echoMemberMethod(arg1){
9-
return arg1 + "-w-i-t-h-"+ this.name;
8+
echoMemberMethod(arg1) {
9+
return arg1 + "-w-i-t-h-" + this.name;
1010
}
1111
toString() {
1212
return `JSData("${this.name}")`;
@@ -146,14 +146,14 @@ export function getClass1() {
146146
// console.log(`getClass1(arg1:${cname !== null ? cname : '<null>'})`)
147147
return cname;
148148
}
149-
149+
let dllExports;
150150
export function invoke1(arg1, name) {
151151
if (globalThis.gc) {
152152
// console.log('globalThis.gc');
153153
globalThis.gc();
154154
}
155155
// console.log(`invoke1: ${name}(arg1:${arg1 !== null ? typeof arg1 : '<null>'})`)
156-
const JavaScriptTestHelper = globalThis.App.EXPORTS.System.Runtime.InteropServices.JavaScript.Tests.JavaScriptTestHelper
156+
const JavaScriptTestHelper = dllExports.System.Runtime.InteropServices.JavaScript.Tests.JavaScriptTestHelper;
157157
const fn = JavaScriptTestHelper[name];
158158

159159
// console.log("invoke1:" + typeof fn);
@@ -164,8 +164,7 @@ export function invoke1(arg1, name) {
164164
}
165165

166166
export function invoke2(arg1, name) {
167-
const JavaScriptTestHelperNoNamespace = globalThis.App.EXPORTS.JavaScriptTestHelperNoNamespace
168-
const fn = JavaScriptTestHelperNoNamespace[name];
167+
const fn = dllExports.JavaScriptTestHelperNoNamespace[name];
169168
//console.log("invoke1:" + fn.toString());
170169
const res = fn(arg1);
171170
// console.log(`invoke1: res ${res !== null ? typeof res : '<null>'}`)
@@ -272,5 +271,8 @@ globalThis.rebound = {
272271
echoMemberMethod: globalThis.data.echoMemberMethod.bind(globalThis.data)
273272
}
274273

274+
export async function setup() {
275+
dllExports = await App.runtime.getAssemblyExports("System.Runtime.InteropServices.JavaScript.Tests.dll");
276+
}
275277

276278
// console.log('JavaScriptTestHelper:' Object.keys(globalThis.JavaScriptTestHelper));

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import createDotnetRuntime from './dotnet.js'
33
try {
44
const { BINDING } = await createDotnetRuntime(({ MONO }) => ({
55
configSrc: "./mono-config.json",
6-
onConfigLoaded: () => {
7-
MONO.config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
6+
onConfigLoaded: (config) => {
7+
config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
88
},
99
}));
1010
const update = BINDING.bind_static_method("[WasmDelta] Sample.Test:Update");

src/mono/sample/wasm/browser-bench/frame-main.js

+18-11
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,31 @@
66
import createDotnetRuntime from './dotnet.js'
77

88
class FrameApp {
9-
async init({ MONO }) {
10-
const exports = await MONO.mono_wasm_get_assembly_exports("Wasm.Browser.Bench.Sample.dll");
9+
async init({ getAssemblyExports }) {
10+
const exports = await getAssemblyExports("Wasm.Browser.Bench.Sample.dll");
1111
exports.Sample.AppStartTask.FrameApp.ReachedManaged();
1212
}
1313

1414
reachedCallback() {
15-
window.parent.resolveAppStartEvent("reached");
15+
if (window.parent != window) {
16+
window.parent.resolveAppStartEvent("reached");
17+
}
1618
}
1719
}
1820

21+
let mute = false;
1922
try {
2023
globalThis.frameApp = new FrameApp();
2124
globalThis.frameApp.ReachedCallback = globalThis.frameApp.reachedCallback.bind(globalThis.frameApp);
22-
23-
let mute = false;
24-
window.addEventListener("pageshow", event => { window.parent.resolveAppStartEvent("pageshow"); })
25+
if (window.parent != window) {
26+
window.addEventListener("pageshow", event => { window.parent.resolveAppStartEvent("pageshow"); })
27+
}
2528

2629
window.muteErrors = () => {
2730
mute = true;
2831
}
2932

30-
const { MONO } = await createDotnetRuntime(() => ({
33+
const runtime = await createDotnetRuntime(() => ({
3134
disableDotnet6Compatibility: true,
3235
configSrc: "./mono-config.json",
3336
printErr: function () {
@@ -36,16 +39,20 @@ try {
3639
}
3740
},
3841
onConfigLoaded: () => {
39-
window.parent.resolveAppStartEvent("onConfigLoaded");
40-
// Module.config.diagnostic_tracing = true;
42+
if (window.parent != window) {
43+
window.parent.resolveAppStartEvent("onConfigLoaded");
44+
}
45+
// Module.config.diagnosticTracing = true;
4146
},
4247
onAbort: (error) => {
4348
wasm_exit(1, error);
4449
},
4550
}));
4651

47-
window.parent.resolveAppStartEvent("onDotnetReady");
48-
await frameApp.init({ MONO });
52+
if (window.parent != window) {
53+
window.parent.resolveAppStartEvent("onDotnetReady");
54+
}
55+
await frameApp.init(runtime);
4956
}
5057
catch (err) {
5158
if (!mute) {

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ let setTasks;
1010
let getFullJsonResults;
1111

1212
class MainApp {
13-
async init({ MONO }) {
14-
const exports = await MONO.mono_wasm_get_assembly_exports("Wasm.Browser.Bench.Sample.dll");
13+
async init({ getAssemblyExports }) {
14+
const exports = await getAssemblyExports("Wasm.Browser.Bench.Sample.dll");
1515
runBenchmark = exports.Sample.Test.RunBenchmark;
1616
setTasks = exports.Sample.Test.SetTasks;
1717
getFullJsonResults = exports.Sample.Test.GetFullJsonResults;
@@ -94,14 +94,14 @@ try {
9494
globalThis.mainApp.FrameReachedManaged = globalThis.mainApp.frameReachedManaged.bind(globalThis.mainApp);
9595
globalThis.mainApp.PageShow = globalThis.mainApp.pageShow.bind(globalThis.mainApp);
9696

97-
const { MONO } = await createDotnetRuntime(() => ({
97+
const runtime = await createDotnetRuntime(() => ({
9898
disableDotnet6Compatibility: true,
9999
configSrc: "./mono-config.json",
100100
onAbort: (error) => {
101101
wasm_exit(1, error);
102102
}
103103
}));
104-
await mainApp.init({ MONO });
104+
await mainApp.init(runtime);
105105
}
106106
catch (err) {
107107
wasm_exit(1, err);

src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@
2020
<ItemGroup>
2121
<WasmExtraFilesToDeploy Include="index.html" />
2222
<WasmExtraFilesToDeploy Include="mock.js" Condition="'$(MonoDiagnosticsMock)' == 'true'"/>
23-
<WasmExtraConfig Condition="true" Include="environment_variables" Value='
23+
<WasmExtraConfig Condition="true" Include="environmentVariables" Value='
2424
{
2525
"MONO_LOG_LEVEL": "warning",
2626
"MONO_LOG_MASK": "all"
2727
}' />
2828
<!-- this option requires running dotnet-dsrouter and a real dotnet-trace client -->
29-
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' != 'true'" Include="diagnostic_options" Value='
29+
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' != 'true'" Include="diagnosticOptions" Value='
3030
{
31-
"server": { "suspend": true, "connect_url": "ws://localhost:8088/diagnostics" }
31+
"server": { "suspend": true, "connectUrl": "ws://localhost:8088/diagnostics" }
3232
}' />
3333
<!-- this option requires compiling the runtime with /p:MonoDiagnosticsMock=true and also building this project with the same property-->
34-
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' == 'true'" Include="diagnostic_options" Value='
34+
<WasmExtraConfig Condition="true and '$(MonoDiagnosticsMock)' == 'true'" Include="diagnosticOptions" Value='
3535
{
36-
"server": { "suspend": false, "connect_url": "mock:./mock.js" }
36+
"server": { "suspend": false, "connectUrl": "mock:./mock.js" }
3737
}' />
3838
<!-- this option will create an EventPipe session at startup, that will dump its data into the Emscripten VFS -->
39-
<WasmExtraConfig Condition="false" Include="diagnostic_options" Value='
39+
<WasmExtraConfig Condition="false" Include="diagnosticOptions" Value='
4040
{
4141
"sessions": [ { "collectRundownEvents": "true", "providers": "WasmHello::5:EventCounterIntervalSec=1" } ]
4242
}' />

src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<ItemGroup>
1515
<WasmExtraFilesToDeploy Include="index.html" />
16-
<WasmExtraConfig Include="environment_variables" Value='
16+
<WasmExtraConfig Include="environmentVariables" Value='
1717
{
1818
"DOTNET_EnableEventPipe": "1",
1919
"DOTNET_EventPipeOutputPath": "/trace.nettrace"

src/mono/sample/wasm/browser-mt-eventpipe/main.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function Uint8ToString(u8a) {
2222
}
2323

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

4545
console.debug(`ret: ${ret}`);
4646

0 commit comments

Comments
 (0)