Skip to content

Commit ca186e4

Browse files
committed
wip
1 parent c8b4842 commit ca186e4

File tree

30 files changed

+2659
-57
lines changed

30 files changed

+2659
-57
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Reflection;
6+
using System.Runtime.CompilerServices;
7+
8+
internal static partial class Interop
9+
{
10+
internal static unsafe partial class Runtime
11+
{
12+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "SystemInteropJS_BindJSImportST")]
13+
public static extern unsafe nint BindJSImportST(void* signature);
14+
15+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "SystemInteropJS_InvokeJSImportST")]
16+
public static extern void InvokeJSImportST(int importHandle, nint args);
17+
18+
/* TODO-WASM
19+
[LibraryImport(RuntimeHelpers.QCall)]
20+
internal static extern void ReleaseCSOwnedObject(nint jsHandle);
21+
22+
[LibraryImport(RuntimeHelpers.QCall)]
23+
public static extern void InvokeJSFunction(nint functionHandle, nint data);
24+
25+
[LibraryImport(RuntimeHelpers.QCall)]
26+
public static extern void ResolveOrRejectPromise(nint data);
27+
28+
[LibraryImport(RuntimeHelpers.QCall)]
29+
public static extern nint RegisterGCRoot(void* start, int bytesSize, IntPtr name);
30+
[LibraryImport(RuntimeHelpers.QCall)]
31+
public static extern void DeregisterGCRoot(nint handle);
32+
33+
[LibraryImport(RuntimeHelpers.QCall)]
34+
public static extern void CancelPromise(nint gcHandle);
35+
36+
[LibraryImport(RuntimeHelpers.QCall)]
37+
public static extern void BindAssemblyExports(IntPtr assemblyNamePtr);
38+
[LibraryImport(RuntimeHelpers.QCall)]
39+
public static extern void GetAssemblyExport(IntPtr assemblyNamePtr, IntPtr namespacePtr, IntPtr classnamePtr, IntPtr methodNamePtr, int signatureHash, IntPtr* monoMethodPtrPtr);
40+
*/
41+
}
42+
}

src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
</ItemGroup>
2424

2525
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'browser'">
26-
<Compile Include="$(CommonPath)Interop\Browser\Interop.Runtime.cs" Link="System\Runtime\InteropServices\JavaScript\Interop\Interop.Runtime.cs" />
26+
<Compile Include="$(CommonPath)Interop\Browser\Interop.Runtime.Mono.cs" Link="System\Runtime\InteropServices\JavaScript\Interop\Interop.Runtime.Mono.cs" Condition="'$(RuntimeFlavor)' == 'Mono'" />
27+
<Compile Include="$(CommonPath)Interop\Browser\Interop.Runtime.CoreCLR.cs" Link="System\Runtime\InteropServices\JavaScript\Interop\Interop.Runtime.CoreCLR.cs" Condition="'$(RuntimeFlavor)' == 'CoreCLR'" />
2728
<Compile Include="System\Runtime\InteropServices\JavaScript\Interop\JavaScriptImports.Generated.cs" />
2829
<Compile Include="System\Runtime\InteropServices\JavaScript\Interop\JavaScriptExports.cs" />
2930

src/mono/browser/runtime/gc-handles.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,24 @@ let _next_gcv_handle = -2;
3131
// GCVHandle is like GCHandle, but it's not tracked and allocated by the mono GC, but just by JS.
3232
// It's used when we need to create GCHandle-like identity ahead of time, before calling Mono.
3333
// they have negative values, so that they don't collide with GCHandles.
34-
export function alloc_gcv_handle (): GCHandle {
34+
export function alloc_gcv_handle(): GCHandle {
3535
const gcv_handle = _gcv_handle_free_list.length ? _gcv_handle_free_list.pop() : _next_gcv_handle--;
3636
return gcv_handle as any;
3737
}
3838

39-
export function free_gcv_handle (gcv_handle: GCHandle): void {
39+
export function free_gcv_handle(gcv_handle: GCHandle): void {
4040
_gcv_handle_free_list.push(gcv_handle);
4141
}
4242

43-
export function is_jsv_handle (js_handle: JSHandle): boolean {
43+
export function is_jsv_handle(js_handle: JSHandle): boolean {
4444
return (js_handle as any) < -1;
4545
}
4646

47-
export function is_js_handle (js_handle: JSHandle): boolean {
47+
export function is_js_handle(js_handle: JSHandle): boolean {
4848
return (js_handle as any) > 0;
4949
}
5050

51-
export function is_gcv_handle (gc_handle: GCHandle): boolean {
51+
export function is_gcv_handle(gc_handle: GCHandle): boolean {
5252
return (gc_handle as any) < -1;
5353
}
5454

@@ -62,15 +62,15 @@ export const cs_owned_js_handle_symbol = Symbol.for("wasm cs_owned_js_handle");
6262
export const do_not_force_dispose = Symbol.for("wasm do_not_force_dispose");
6363

6464

65-
export function mono_wasm_get_jsobj_from_js_handle (js_handle: JSHandle): any {
65+
export function mono_wasm_get_jsobj_from_js_handle(js_handle: JSHandle): any {
6666
if (is_js_handle(js_handle))
6767
return _cs_owned_objects_by_js_handle[<any>js_handle];
6868
if (is_jsv_handle(js_handle))
6969
return _cs_owned_objects_by_jsv_handle[0 - <any>js_handle];
7070
return null;
7171
}
7272

73-
export function mono_wasm_get_js_handle (js_obj: any): JSHandle {
73+
export function mono_wasm_get_js_handle(js_obj: any): JSHandle {
7474
assert_js_interop();
7575
if (js_obj[cs_owned_js_handle_symbol]) {
7676
return js_obj[cs_owned_js_handle_symbol];
@@ -94,7 +94,7 @@ export function mono_wasm_get_js_handle (js_obj: any): JSHandle {
9494
return js_handle as JSHandle;
9595
}
9696

97-
export function register_with_jsv_handle (js_obj: any, jsv_handle: JSHandle) {
97+
export function register_with_jsv_handle(js_obj: any, jsv_handle: JSHandle) {
9898
assert_js_interop();
9999
// note _cs_owned_objects_by_js_handle is list, not Map. That's why we maintain _js_handle_free_list.
100100
_cs_owned_objects_by_jsv_handle[0 - <any>jsv_handle] = js_obj;
@@ -105,7 +105,7 @@ export function register_with_jsv_handle (js_obj: any, jsv_handle: JSHandle) {
105105
}
106106

107107
// note: in MT, this is called from locked JSProxyContext. Don't call anything that would need locking.
108-
export function SystemInteropJS_ReleaseCSOwnedObject (js_handle: JSHandle): void {
108+
export function SystemInteropJS_ReleaseCSOwnedObject(js_handle: JSHandle): void {
109109
let obj: any;
110110
if (is_js_handle(js_handle)) {
111111
obj = _cs_owned_objects_by_js_handle[<any>js_handle];
@@ -122,7 +122,7 @@ export function SystemInteropJS_ReleaseCSOwnedObject (js_handle: JSHandle): void
122122
}
123123
}
124124

125-
export function setup_managed_proxy (owner: any, gc_handle: GCHandle): void {
125+
export function setup_managed_proxy(owner: any, gc_handle: GCHandle): void {
126126
assert_js_interop();
127127
// keep the gc_handle so that we could easily convert it back to original C# object for roundtrip
128128
owner[js_owned_gc_handle_symbol] = gc_handle;
@@ -139,15 +139,15 @@ export function setup_managed_proxy (owner: any, gc_handle: GCHandle): void {
139139
_js_owned_object_table.set(gc_handle, wr);
140140
}
141141

142-
export function upgrade_managed_proxy_to_strong_ref (owner: any, gc_handle: GCHandle): void {
142+
export function upgrade_managed_proxy_to_strong_ref(owner: any, gc_handle: GCHandle): void {
143143
const sr = create_strong_ref(owner);
144144
if (_use_finalization_registry) {
145145
_js_owned_object_registry.unregister(owner);
146146
}
147147
_js_owned_object_table.set(gc_handle, sr);
148148
}
149149

150-
export function teardown_managed_proxy (owner: any, gc_handle: GCHandle, skipManaged?: boolean): void {
150+
export function teardown_managed_proxy(owner: any, gc_handle: GCHandle, skipManaged?: boolean): void {
151151
assert_js_interop();
152152
// The JS object associated with this gc_handle has been collected by the JS GC.
153153
// As such, it's not possible for this gc_handle to be invoked by JS anymore, so
@@ -171,21 +171,21 @@ export function teardown_managed_proxy (owner: any, gc_handle: GCHandle, skipMan
171171
}
172172
}
173173

174-
export function assert_not_disposed (result: any): GCHandle {
174+
export function assert_not_disposed(result: any): GCHandle {
175175
const gc_handle = result[js_owned_gc_handle_symbol];
176176
mono_check(gc_handle != GCHandleNull, "ObjectDisposedException");
177177
return gc_handle;
178178
}
179179

180-
function _js_owned_object_finalized (gc_handle: GCHandle): void {
180+
function _js_owned_object_finalized(gc_handle: GCHandle): void {
181181
if (!loaderHelpers.is_runtime_running()) {
182182
// We're shutting down, so don't bother doing anything else.
183183
return;
184184
}
185185
teardown_managed_proxy(null, gc_handle);
186186
}
187187

188-
export function _lookup_js_owned_object (gc_handle: GCHandle): any {
188+
export function _lookup_js_owned_object(gc_handle: GCHandle): any {
189189
if (!gc_handle)
190190
return null;
191191
const wr = _js_owned_object_table.get(gc_handle);
@@ -197,7 +197,7 @@ export function _lookup_js_owned_object (gc_handle: GCHandle): any {
197197
return null;
198198
}
199199

200-
export function assertNoProxies (): void {
200+
export function assertNoProxies(): void {
201201
if (!WasmEnableThreads) return;
202202
mono_assert(_js_owned_object_table.size === 0, "There should be no proxies on this thread.");
203203
mono_assert(_cs_owned_objects_by_js_handle.length === 1, "There should be no proxies on this thread.");
@@ -210,7 +210,7 @@ let force_dispose_proxies_in_progress = false;
210210

211211
// when we arrive here from UninstallWebWorkerInterop, the C# will unregister the handles too.
212212
// when called from elsewhere, C# side could be unbalanced!!
213-
export function forceDisposeProxies (disposeMethods: boolean, verbose: boolean): void {
213+
export function forceDisposeProxies(disposeMethods: boolean, verbose: boolean): void {
214214
let keepSomeCsAlive = false;
215215
let keepSomeJsAlive = false;
216216
force_dispose_proxies_in_progress = true;

src/native/corehost/browserhost/loader/bootstrap.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { dotnetAssert, dotnetGetInternals, dotnetBrowserHostExports, dotnetUpdat
77
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL } from "./per-module";
88
import { getLoaderConfig } from "./config";
99
import { BrowserHost_InitializeCoreCLR } from "./run";
10-
import { createPromiseController } from "./promise-controller";
10+
import { createPromiseCompletionSource } from "./promise-completion-source";
1111
import { node_fs, node_url } from "./polyfills";
1212

1313
const scriptUrlQuery = /*! webpackIgnore: true */import.meta.url;
@@ -16,7 +16,7 @@ const modulesUniqueQuery = queryIndex > 0 ? scriptUrlQuery.substring(queryIndex)
1616
const scriptUrl = normalizeFileUrl(scriptUrlQuery);
1717
const scriptDirectory = normalizeDirectoryUrl(scriptUrl);
1818

19-
const nativeModulePromiseController = createPromiseController<EmscriptenModuleInternal>(() => {
19+
const nativeModulePromiseController = createPromiseCompletionSource<EmscriptenModuleInternal>(() => {
2020
dotnetUpdateInternals(dotnetGetInternals());
2121
});
2222

src/native/corehost/browserhost/loader/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { check, error, info, warn, debug } from "./logging";
1818

1919
import { dotnetAssert, dotnetLoaderExports, dotnetLogger, dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module";
2020
import { rejectRunMainPromise, resolveRunMainPromise, getRunMainPromise } from "./run";
21+
import { createPromiseCompletionSource } from "./promise-completion-source";
2122

2223
export function dotnetInitializeModule(): RuntimeAPI {
2324

@@ -53,6 +54,7 @@ export function dotnetInitializeModule(): RuntimeAPI {
5354
getRunMainPromise,
5455
rejectRunMainPromise,
5556
resolveRunMainPromise,
57+
createPromiseCompletionSource,
5658
};
5759
Object.assign(dotnetLoaderExports, loaderFunctions);
5860
const logger: LoggerType = {
@@ -82,6 +84,7 @@ export function dotnetInitializeModule(): RuntimeAPI {
8284
dotnetLoaderExports.resolveRunMainPromise,
8385
dotnetLoaderExports.rejectRunMainPromise,
8486
dotnetLoaderExports.getRunMainPromise,
87+
dotnetLoaderExports.createPromiseCompletionSource,
8588
];
8689
}
8790
}

src/native/corehost/browserhost/loader/logging.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ export function check(condition: unknown, messageFactory: string | (() => string
1414

1515
const prefix = "DOTNET: ";
1616

17-
export function info(msg: string, ...data: any) {
18-
console.info(prefix + msg, ...data);
17+
export function debug(msg: string | (() => string), ...data: any) {
18+
if (typeof msg === "function") {
19+
msg = msg();
20+
}
21+
console.debug(prefix + msg, ...data);
1922
}
2023

21-
export function debug(msg: string, ...data: any) {
22-
console.debug(prefix + msg, ...data);
24+
export function info(msg: string, ...data: any) {
25+
console.info(prefix + msg, ...data);
2326
}
2427

2528
export function warn(msg: string, ...data: any) {

src/native/corehost/browserhost/loader/promise-controller.ts renamed to src/native/corehost/browserhost/loader/promise-completion-source.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
import type { ControllablePromise, PromiseController } from "./types";
4+
import type { ControllablePromise, PromiseCompletionSource } from "./types";
55

66
/// a unique symbol used to mark a promise as controllable
7-
export const promiseControlSymbol = Symbol.for("wasm promise control");
8-
9-
// WASM-TODO: PromiseCompletionSource
7+
export const promiseCompletionSourceSymbol = Symbol.for("wasm promise control");
108

119
/// Creates a new promise together with a controller that can be used to resolve or reject that promise.
1210
/// Optionally takes callbacks to be called immediately after a promise is resolved or rejected.
13-
export function createPromiseController<T>(afterResolve?: () => void, afterReject?: () => void): PromiseController<T> {
14-
let promiseControl: PromiseController<T> = null as unknown as PromiseController<T>;
11+
export function createPromiseCompletionSource<T>(afterResolve?: () => void, afterReject?: () => void): PromiseCompletionSource<T> {
12+
let promiseControl: PromiseCompletionSource<T> = null as unknown as PromiseCompletionSource<T>;
1513
const promise = new Promise<T>((resolve, reject) => {
1614
promiseControl = {
1715
isDone: false,
@@ -41,16 +39,16 @@ export function createPromiseController<T>(afterResolve?: () => void, afterRejec
4139
});
4240
(<any>promiseControl).promise = promise;
4341
const controllablePromise = promise as ControllablePromise<T>;
44-
(controllablePromise as any)[promiseControlSymbol] = promiseControl;
42+
(controllablePromise as any)[promiseCompletionSourceSymbol] = promiseControl;
4543
return promiseControl;
4644
}
4745

48-
export function getPromiseController<T>(promise: ControllablePromise<T>): PromiseController<T>;
49-
export function getPromiseController<T>(promise: Promise<T>): PromiseController<T> | undefined {
50-
return (promise as any)[promiseControlSymbol];
46+
export function getPromiseCompletionSource<T>(promise: ControllablePromise<T>): PromiseCompletionSource<T>;
47+
export function getPromiseCompletionSource<T>(promise: Promise<T>): PromiseCompletionSource<T> | undefined {
48+
return (promise as any)[promiseCompletionSourceSymbol];
5149
}
5250

5351
export function isControllablePromise<T>(promise: Promise<T>): promise is ControllablePromise<T> {
54-
return (promise as any)[promiseControlSymbol] !== undefined;
52+
return (promise as any)[promiseCompletionSourceSymbol] !== undefined;
5553
}
5654

src/native/corehost/browserhost/loader/run.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { DotnetHostBuilder } from "../types";
55
import { findResources, isNodeHosted, isShellHosted } from "./bootstrap";
66
import { Module, dotnetAssert } from "./cross-module";
77
import { exit } from "./exit";
8-
import { createPromiseController } from "./promise-controller";
8+
import { createPromiseCompletionSource } from "./promise-completion-source";
99

1010
let CoreCLRInitialized = false;
11-
const runMainPromiseController = createPromiseController<number>();
11+
const runMainPromiseController = createPromiseCompletionSource<number>();
1212

1313
export function BrowserHost_InitializeCoreCLR(): void {
1414
dotnetAssert.check(!CoreCLRInitialized, "CoreCLR should be initialized just once");

src/native/libs/Common/JavaScript/CMakeLists.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ set(ROLLUP_TS_SOURCES
2323
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/bootstrap.ts"
2424
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/config.ts"
2525
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/cross-module.ts"
26-
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/dotnet.ts"
2726
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/dotnet.d.ts"
27+
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/dotnet.ts"
2828
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/exit.ts"
2929
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/host-builder.ts"
3030
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/index.ts"
3131
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/lib-initializers.ts"
3232
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/logging.ts"
3333
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/per-module.ts"
3434
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/polyfills.ts"
35-
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/promise-controller.ts"
35+
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/promise-completion-source.ts"
3636
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/run.ts"
3737
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/types.ts"
3838
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/types.ts"
@@ -54,9 +54,9 @@ set(ROLLUP_TS_SOURCES
5454
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/crypto.ts"
5555
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/globalization-locale.ts"
5656
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/index.ts"
57-
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/timer.ts"
5857
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/main.ts"
5958
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/per-module.ts"
59+
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/native/timer.ts"
6060
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/types.ts"
6161
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/utils/cdac.ts"
6262
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/utils/cross-module.ts"
@@ -70,9 +70,17 @@ set(ROLLUP_TS_SOURCES
7070
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/utils/types.ts"
7171
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/dotnet.runtime.ts"
7272
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/cross-module.ts"
73+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/gc-handles.ts"
7374
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts"
75+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/invoke-cs.ts"
76+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/invoke-js.ts"
77+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts"
78+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-js.ts"
79+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal.ts"
7480
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/per-module.ts"
7581
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/types.ts"
82+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/utils.ts"
83+
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/interop/weak-ref.ts"
7684
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/native/cross-linked.ts"
7785
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/native/index.ts"
7886
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/types.ts"

0 commit comments

Comments
 (0)