Skip to content

Commit 2022040

Browse files
lewingpavelsavara
authored andcommitted
[browser][MT] fix various issues and enable System.Runtime.InteropServices.JavaScript.Tests (dotnet#99000)
Co-authored-by: Pavel Savara <pavel.savara@gmail.com>
1 parent 92c1a9e commit 2022040

File tree

7 files changed

+34
-16
lines changed

7 files changed

+34
-16
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ private void Dispose(bool disposing)
517517
{
518518
Environment.FailFast($"JSProxyContext must be disposed on the thread which owns it, ManagedThreadId: {Environment.CurrentManagedThreadId}. {Environment.NewLine} {Environment.StackTrace}");
519519
}
520-
((GCHandle)ContextHandle).Free();
521520
#endif
522521

523522
List<WeakReference<JSObject>> copy = new(ThreadCsOwnedObjects.Values);
@@ -531,6 +530,7 @@ private void Dispose(bool disposing)
531530

532531
#if FEATURE_WASM_MANAGED_THREADS
533532
Interop.Runtime.UninstallWebWorkerInterop();
533+
((GCHandle)ContextHandle).Free();
534534
#endif
535535

536536
foreach (var gch in ThreadJsOwnedObjects.Values)
@@ -544,6 +544,7 @@ private void Dispose(bool disposing)
544544
{
545545
holder.Callback!.Invoke(null);
546546
}
547+
((GCHandle)holder.GCHandle).Free();
547548
}
548549

549550
ThreadCsOwnedObjects.Clear();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ private void Pump()
257257
}
258258
try
259259
{
260+
if (SynchronizationContext.Current == null)
261+
{
262+
SetSynchronizationContext(this);
263+
}
260264
while (Queue.Reader.TryRead(out var item))
261265
{
262266
try

src/libraries/tests.proj

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,6 @@
398398
<!-- Issue: https://github.com/dotnet/runtime/issues/95795 -->
399399
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Tests\Hybrid\System.Globalization.Hybrid.WASM.Tests.csproj" />
400400
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Calendars.Tests\Hybrid\System.Globalization.Calendars.Hybrid.WASM.Tests.csproj" />
401-
<!-- Issue: https://github.com/dotnet/runtime/issues/98406 -->
402-
<!-- Issue: https://github.com/dotnet/runtime/issues/98101 -->
403-
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" />
404401
</ItemGroup>
405402

406403
<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(WasmEnableThreads)' != 'true' and '$(RunDisabledWasmTests)' != 'true'">
@@ -616,9 +613,7 @@
616613
<!-- Don't want the default smoke tests - just verify that threading works -->
617614
<SmokeTestProject Remove="@(SmokeTestProject)" />
618615
<SmokeTestProject Include="$(MonoProjectRoot)sample\wasm\browser-threads\Wasm.Browser.Threads.Sample.csproj" />
619-
<!-- Issue: https://github.com/dotnet/runtime/issues/98406 -->
620-
<!-- Issue: https://github.com/dotnet/runtime/issues/98101 -->
621-
<!-- <SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" /> -->
616+
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" />
622617
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Net.WebSockets.Client\tests\System.Net.WebSockets.Client.Tests.csproj" />
623618
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Net.Http\tests\FunctionalTests\System.Net.Http.Functional.Tests.csproj" />
624619
</ItemGroup>

src/mono/browser/runtime/cancelable-promise.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ export class PromiseHolder extends ManagedObject {
7878
}
7979

8080
resolve(data: any) {
81-
mono_assert(!this.isResolved, "resolve could be called only once");
82-
mono_assert(!this.isDisposed, "resolve is already disposed.");
8381
if (!loaderHelpers.is_runtime_running()) {
8482
mono_log_debug("This promise resolution can't be propagated to managed code, mono runtime already exited.");
8583
return;
8684
}
85+
mono_assert(!this.isResolved, "resolve could be called only once");
86+
mono_assert(!this.isDisposed, "resolve is already disposed.");
8787
if (WasmEnableThreads && !this.setIsResolving()) {
8888
// we know that cancelation is in flight
8989
// because we need to keep the GCHandle alive until until the cancelation arrives
@@ -102,12 +102,12 @@ export class PromiseHolder extends ManagedObject {
102102
}
103103

104104
reject(reason: any) {
105-
mono_assert(!this.isResolved, "reject could be called only once");
106-
mono_assert(!this.isDisposed, "resolve is already disposed.");
107105
if (!loaderHelpers.is_runtime_running()) {
108106
mono_log_debug("This promise rejection can't be propagated to managed code, mono runtime already exited.");
109107
return;
110108
}
109+
mono_assert(!this.isResolved, "reject could be called only once");
110+
mono_assert(!this.isDisposed, "resolve is already disposed.");
111111
const isCancelation = reason && reason[promise_holder_symbol] === this;
112112
if (WasmEnableThreads && !isCancelation && !this.setIsResolving()) {
113113
// we know that cancelation is in flight
@@ -127,6 +127,10 @@ export class PromiseHolder extends ManagedObject {
127127
}
128128

129129
cancel() {
130+
if (!loaderHelpers.is_runtime_running()) {
131+
mono_log_debug("This promise cancelation can't be propagated to managed code, mono runtime already exited.");
132+
return;
133+
}
130134
mono_assert(!this.isResolved, "cancel could be called only once");
131135
mono_assert(!this.isDisposed, "resolve is already disposed.");
132136

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export function teardown_managed_proxy(owner: any, gc_handle: GCHandle, skipMana
160160
}
161161
}
162162
if (gc_handle !== GCHandleNull && _js_owned_object_table.delete(gc_handle) && !skipManaged) {
163-
if (loaderHelpers.is_runtime_running()) {
163+
if (loaderHelpers.is_runtime_running() && !force_dispose_proxies_in_progress) {
164164
release_js_owned_object_by_gc_handle(gc_handle);
165165
}
166166
}
@@ -204,11 +204,14 @@ export function assertNoProxies(): void {
204204
mono_assert(js_import_wrapper_by_fn_handle.length === 1, "There should be no imports on this thread.");
205205
}
206206

207+
let force_dispose_proxies_in_progress = false;
208+
207209
// when we arrive here from UninstallWebWorkerInterop, the C# will unregister the handles too.
208210
// when called from elsewhere, C# side could be unbalanced!!
209211
export function forceDisposeProxies(disposeMethods: boolean, verbose: boolean): void {
210212
let keepSomeCsAlive = false;
211213
let keepSomeJsAlive = false;
214+
force_dispose_proxies_in_progress = true;
212215

213216
let doneImports = 0;
214217
let doneExports = 0;

src/mono/browser/runtime/http.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ function commonAsserts(controller: HttpController) {
2525
mono_assert(controller, "expected controller");
2626
}
2727

28+
let http_wasm_supports_streaming_request_cached: boolean | undefined;
2829
export function http_wasm_supports_streaming_request(): boolean {
30+
if (http_wasm_supports_streaming_request_cached !== undefined) {
31+
return http_wasm_supports_streaming_request_cached;
32+
}
2933
// Detecting streaming request support works like this:
3034
// If the browser doesn't support a particular body type, it calls toString() on the object and uses the result as the body.
3135
// So, if the browser doesn't support request streams, the request body becomes the string "[object ReadableStream]".
@@ -43,13 +47,20 @@ export function http_wasm_supports_streaming_request(): boolean {
4347
return "half";
4448
},
4549
} as RequestInit /* https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483 */).headers.has("Content-Type");
46-
return duplexAccessed && !hasContentType;
50+
http_wasm_supports_streaming_request_cached = duplexAccessed && !hasContentType;
51+
} else {
52+
http_wasm_supports_streaming_request_cached = false;
4753
}
48-
return false;
54+
return http_wasm_supports_streaming_request_cached;
4955
}
5056

57+
let http_wasm_supports_streaming_response_cached: boolean | undefined;
5158
export function http_wasm_supports_streaming_response(): boolean {
52-
return typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function";
59+
if (http_wasm_supports_streaming_response_cached !== undefined) {
60+
return http_wasm_supports_streaming_response_cached;
61+
}
62+
http_wasm_supports_streaming_response_cached = typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function";
63+
return http_wasm_supports_streaming_response_cached;
5364
}
5465

5566
export function http_wasm_create_controller(): HttpController {

src/mono/browser/runtime/marshal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ export function set_arg_element_type(arg: JSMarshalerArgument, type: MarshalerTy
202202

203203
export function get_arg_bool(arg: JSMarshalerArgument): boolean {
204204
mono_assert(arg, "Null arg");
205-
return getB32(<any>arg);
205+
return !!getU8(<any>arg);
206206
}
207207

208208
export function get_arg_u8(arg: JSMarshalerArgument): number {

0 commit comments

Comments
 (0)