From 377a8e4678f65715296aaa8b472117aa956d9d88 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 27 Jan 2021 11:12:35 +0100 Subject: [PATCH 01/19] [browser] Fix System.Delegate.DynamicInvoke method can not be resolved - When building an app using true the linker is linking out System.Delegate.DynamicInvoke - Add this to the linker trim exclusions. --- .../src/ILLink/ILLinkTrim.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml index 7587cdc31bb9c4..81573873beb168 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml @@ -2,4 +2,12 @@ + + + + + + From ddb04850c2d921ac1dc70a6d2ec39a185afbc436 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 27 Jan 2021 14:57:18 +0100 Subject: [PATCH 02/19] Address review comment for assembly name --- .../src/ILLink/ILLinkTrim.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml index 81573873beb168..11b84878e8d025 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml @@ -5,7 +5,7 @@ - + From 84c0ba6ae1c20cd3ebb099afdca708efb2f05590 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 27 Jan 2021 16:08:03 +0100 Subject: [PATCH 03/19] Change this back to mscorlib as the recommended code cause a warning. ``` resource System.Private.Runtime.InteropServices.JavaScript.xml in System.Private.Runtime.InteropServices.JavaScript, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a : warning IL2007: Could not resolve assembly 'System.Private.CoreLib' [/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj] 1 Warning(s) 0 Error(s) ``` --- .../src/ILLink/ILLinkTrim.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml index 11b84878e8d025..81573873beb168 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml @@ -5,7 +5,7 @@ - + From ab9ae202600ada3bf0f755726196f0ed4c6ef8b4 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 05:22:51 +0100 Subject: [PATCH 04/19] [browser] Remove linker trim exclusions for System.Delegate.DynamicInvoke --- .../src/ILLink/ILLinkTrim.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml index 81573873beb168..7587cdc31bb9c4 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/ILLink/ILLinkTrim.xml @@ -2,12 +2,4 @@ - - - - - - From 2070cb52cd70aca32d3a725b931f9407c8e0b8dc Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 10:00:48 +0100 Subject: [PATCH 05/19] Remove dependency on System.Delegate.DynamicInvoke - Explicitly provide the declaring type to GetMethodFromHandle in GetCallSignature - Fixes error resolving generic method handles. ``` Error: System.ArgumentException: Cannot resolve method Int32 Invoke(Int32, Int32) because the declaring type of the method handle System.Func`3[T1,T2,TResult] is generic. Explicitly provide the declaring type to GetMethodFromHandle. ``` --- .../InteropServices/JavaScript/Runtime.cs | 4 +-- src/mono/wasm/runtime/binding_support.js | 28 ++++++++----------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index b727661ba0a0c5..d4c843af4b9373 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -262,12 +262,12 @@ private struct IntPtrAndHandle internal RuntimeMethodHandle handle; } - private static string GetCallSignature(IntPtr methodHandle) + private static string GetCallSignature(IntPtr methodHandle, object objForRuntimeType) { IntPtrAndHandle tmp = default(IntPtrAndHandle); tmp.ptr = methodHandle; - MethodBase? mb = MethodBase.GetMethodFromHandle(tmp.handle); + MethodBase? mb = objForRuntimeType == null ? MethodBase.GetMethodFromHandle(tmp.handle) : MethodBase.GetMethodFromHandle(tmp.handle, Type.GetTypeHandle(objForRuntimeType)); if (mb == null) return string.Empty; diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index 34dac476e1ea5d..8662c850babd57 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -780,10 +780,10 @@ var BindingSupportLib = { return this.wasm_get_raw_obj (js_obj.__mono_gchandle__); }, - mono_method_get_call_signature: function(method) { + mono_method_get_call_signature: function(method, mono_obj) { this.bindings_lazy_init (); - return this.call_method (this.get_call_sig, null, "i", [ method ]); + return this.call_method (this.get_call_sig, null, "im", [ method, mono_obj ]); }, get_task_and_bind: function (tcs, js_obj) { @@ -1459,21 +1459,15 @@ var BindingSupportLib = { var [delegateRoot, argsRoot] = MONO.mono_wasm_new_roots ([this.extract_mono_obj (delegate_obj), undefined]); try { - if (!this.delegate_dynamic_invoke) { - if (!this.corlib) - this.corlib = this.assembly_load ("System.Private.CoreLib"); - if (!this.delegate_class) - this.delegate_class = this.find_class (this.corlib, "System", "Delegate"); - if (!this.delegate_class) - { - throw new Error("System.Delegate class can not be resolved."); - } - this.delegate_dynamic_invoke = this.find_method (this.delegate_class, "DynamicInvoke", -1); - } - argsRoot.value = this.js_array_to_mono_array (js_args); - if (!this.delegate_dynamic_invoke) - throw new Error("System.Delegate.DynamicInvoke method can not be resolved."); - return this.call_method (this.delegate_dynamic_invoke, delegateRoot.value, "m", [ argsRoot.value ]); + if (typeof delegate_obj.__mono_delegate_invoke__ === "undefined") + delegate_obj.__mono_delegate_invoke__ = this.mono_wasm_get_delegate_invoke(delegateRoot.value); + if (!delegate_obj.__mono_delegate_invoke__) + throw new Error("System.Delegate Invoke method can not be resolved."); + + if (typeof delegate_obj.__mono_delegate_invoke_sig__ === "undefined") + delegate_obj.__mono_delegate_invoke_sig__ = Module.mono_method_get_call_signature (delegate_obj.__mono_delegate_invoke__, delegateRoot.value); + + return this.call_method (delegate_obj.__mono_delegate_invoke__, delegateRoot.value, delegate_obj.__mono_delegate_invoke_sig__, js_args); } finally { MONO.mono_wasm_release_roots (delegateRoot, argsRoot); } From 255be2f036a3efdb47926f5c43aabba7d014c613 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 10:04:45 +0100 Subject: [PATCH 06/19] Add method to retrieve the Invoke method of the delegate --- src/mono/wasm/runtime/binding_support.js | 1 + src/mono/wasm/runtime/driver.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index 8662c850babd57..851db381884e6a 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -69,6 +69,7 @@ var BindingSupportLib = { this.mono_wasm_box_primitive = Module.cwrap ('mono_wasm_box_primitive', 'number', ['number', 'number', 'number']); this.mono_wasm_intern_string = Module.cwrap ('mono_wasm_intern_string', 'number', ['number']); this.assembly_get_entry_point = Module.cwrap ('mono_wasm_assembly_get_entry_point', 'number', ['number']); + this.mono_wasm_get_delegate_invoke = Module.cwrap ('mono_wasm_get_delegate_invoke', 'number', ['number']); this._box_buffer = Module._malloc(16); this._unbox_buffer = Module._malloc(16); diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index a906b3a440e317..a4a0fcb1138faf 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -608,6 +608,12 @@ mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int argument return mono_class_get_method_from_name (klass, name, arguments); } +EMSCRIPTEN_KEEPALIVE MonoMethod* +mono_wasm_get_delegate_invoke (MonoObject *delegate) +{ + return mono_get_delegate_invoke(mono_object_get_class (delegate)); +} + EMSCRIPTEN_KEEPALIVE MonoObject* mono_wasm_box_primitive (MonoClass *klass, void *value, int value_size) { From 7203cbf59bfd37d02eb82c277daebc0300b6a511 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 10:22:37 +0100 Subject: [PATCH 07/19] Create another test module for Delegate tests --- ...me.InteropServices.JavaScript.Tests.csproj | 3 ++- .../JavaScript/DelegateTests.cs | 26 +++++++++++++++++++ .../JavaScript/MarshalTests.cs | 14 ---------- 3 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj index 11dec891deeeb0..e97ca510a53848 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System.Private.Runtime.InteropServices.JavaScript.Tests.csproj @@ -12,8 +12,9 @@ + - + diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs new file mode 100644 index 00000000000000..8fbe9029a89602 --- /dev/null +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices.JavaScript; +using System.Collections.Generic; +using Xunit; + +namespace System.Runtime.InteropServices.JavaScript.Tests +{ + public static class DelegateTests + { + [Fact] + public static void MarshalDelegate() + { + HelperMarshal._object1 = null; + Runtime.InvokeJS(@" + var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); + var res = funcDelegate (10, 20); + App.call_test_method (""InvokeI32"", [ res, res ]); + "); + + Assert.Equal(30, HelperMarshal._functionResultValue); + Assert.Equal(60, HelperMarshal._i32Value); + } + } +} diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs index e15716f4f348e4..934673c31d2376 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs @@ -254,20 +254,6 @@ public static void JSObjectAsFunction() Assert.Equal(50, HelperMarshal._jsAddAsFunctionResult); } - [Fact] - public static void MarshalDelegate() - { - HelperMarshal._object1 = null; - Runtime.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(30, HelperMarshal._functionResultValue); - Assert.Equal(60, HelperMarshal._i32Value); - } - [Fact] public static void BindStaticMethod() { From cbbcbd9135d0dfe81f85f224ea3ad5608c3d7983 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 10:50:05 +0100 Subject: [PATCH 08/19] Add MarshalFunctionReturnAction that marshals an Action delegate from a Function --- .../JavaScript/DelegateTests.cs | 17 +++++++++- .../JavaScript/HelperMarshal.cs | 34 +++++++++++++------ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 8fbe9029a89602..dd842e6c5d33c0 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -10,7 +10,7 @@ namespace System.Runtime.InteropServices.JavaScript.Tests public static class DelegateTests { [Fact] - public static void MarshalDelegate() + public static void MarshalFunction() { HelperMarshal._object1 = null; Runtime.InvokeJS(@" @@ -22,5 +22,20 @@ public static void MarshalDelegate() Assert.Equal(30, HelperMarshal._functionResultValue); Assert.Equal(60, HelperMarshal._i32Value); } + + [Fact] + public static void MarshalFunctionReturnAction() + { + HelperMarshal._object1 = null; + Runtime.InvokeJS(@" + var funcDelegate = App.call_test_method (""CreateFunctionDelegateWithAction"", [ ]); + var actionDelegate = funcDelegate (10, 20); + actionDelegate(30,40); + "); + + Assert.Equal(30, HelperMarshal._functionActionResultValue); + Assert.Equal(70, HelperMarshal._functionActionResultValueOfAction); + } + } } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index 968d386c909214..da46c15ed595e5 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -128,16 +128,6 @@ private static void UseAsFunction(Function func) _jsAddAsFunctionResult = (int)func.Call(null, 20, 30); } - internal static int _functionResultValue; - private static Func CreateFunctionDelegate() - { - return (a, b) => - { - _functionResultValue = a + b; - return _functionResultValue; - }; - } - internal static int _intValue; private static void InvokeInt(int value) { @@ -382,6 +372,30 @@ private static UInt64 GetUInt64() { return UInt64.MaxValue; } + + internal static int _functionResultValue; + private static Func CreateFunctionDelegate() + { + return (a, b) => + { + _functionResultValue = a + b; + return _functionResultValue; + }; + } + + internal static int _functionActionResultValue; + internal static int _functionActionResultValueOfAction; + private static Func> CreateFunctionDelegateWithAction() + { + return (a, b) => + { + _functionActionResultValue = a + b; + return (i1, i2) => + { + _functionActionResultValueOfAction = i1 + i2; + }; + }; + } } public enum TestEnum : uint { From 71456969f554af37071ff3c9066713ce7779fd4d Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 29 Jan 2021 12:05:21 +0100 Subject: [PATCH 09/19] More tests, Actions and Delegate methods --- .../JavaScript/DelegateTests.cs | 98 ++++++++++++++++++- .../JavaScript/HelperMarshal.cs | 55 +++++++++++ 2 files changed, 151 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index dd842e6c5d33c0..11aa7a00cfc04f 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -12,10 +12,32 @@ public static class DelegateTests [Fact] public static void MarshalFunction() { - HelperMarshal._object1 = null; + HelperMarshal._functionResultValue = 0; + HelperMarshal._i32Value = 0; + + Runtime.InvokeJS(@" + var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); + var res = funcDelegate (10, 20); + App.call_test_method (""InvokeI32"", [ res, res ]); + "); + + Assert.Equal(30, HelperMarshal._functionResultValue); + Assert.Equal(60, HelperMarshal._i32Value); + } + + [Fact] + public static void MarshalFunctionLooptyLoop() + { + HelperMarshal._functionResultValue = 0; + HelperMarshal._i32Value = 0; + Runtime.InvokeJS(@" var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); var res = funcDelegate (10, 20); + for (x = 0; x < 1000; x++) + { + res = funcDelegate (10, 20); + } App.call_test_method (""InvokeI32"", [ res, res ]); "); @@ -23,10 +45,31 @@ public static void MarshalFunction() Assert.Equal(60, HelperMarshal._i32Value); } + [Fact] + public static void MarshalFunctionLooptyLoopIncrement() + { + HelperMarshal._functionResultValue = 0; + HelperMarshal._i32Value = 0; + Runtime.InvokeJS(@" + var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); + var res = funcDelegate (10, 20); + for (x = 0; x < 1000; x++) + { + res = funcDelegate (x, x); + } + App.call_test_method (""InvokeI32"", [ res, res ]); + "); + + Assert.Equal(1998, HelperMarshal._functionResultValue); + Assert.Equal(3996, HelperMarshal._i32Value); + } + [Fact] public static void MarshalFunctionReturnAction() { - HelperMarshal._object1 = null; + HelperMarshal._functionActionResultValue = 0; + HelperMarshal._functionActionResultValueOfAction = 0; + Runtime.InvokeJS(@" var funcDelegate = App.call_test_method (""CreateFunctionDelegateWithAction"", [ ]); var actionDelegate = funcDelegate (10, 20); @@ -37,5 +80,56 @@ public static void MarshalFunctionReturnAction() Assert.Equal(70, HelperMarshal._functionActionResultValueOfAction); } + [Fact] + public static void MarshalActionIntInt() + { + HelperMarshal._actionResultValue = 0; + + Runtime.InvokeJS(@" + var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); + actionDelegate(30,40); + "); + + Assert.Equal(70, HelperMarshal._actionResultValue); + } + + [Fact] + public static void MarshalActionFloatIntToIntInt() + { + HelperMarshal._actionResultValue = 0; + Runtime.InvokeJS(@" + var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); + actionDelegate(3.14,40); + "); + + Assert.Equal(43, HelperMarshal._actionResultValue); + } + + [Fact] + public static void MarshalDelegateMethod() + { + HelperMarshal._delMethodResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateDelegateMethod"", [ ]); + del(""Hic sunt dracones""); + "); + + Assert.Equal("Hic sunt dracones", HelperMarshal._delMethodResultValue); + } + + [Fact] + public static void MarshalDelegateMethodReturnString() + { + HelperMarshal._delMethodStringResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateDelegateMethodReturnString"", [ ]); + var res = del(""Hic sunt dracones""); + console.log(res); + App.call_test_method (""SetTestString1"", [ res ]); + "); + + Assert.Equal("Received: Hic sunt dracones", HelperMarshal._delMethodStringResultValue); + } + } } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index da46c15ed595e5..1774d0069bb6ba 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -396,6 +396,61 @@ private static Func> CreateFunctionDelegateWithAction( }; }; } + + internal static int _actionResultValue; + private static Action CreateActionDelegate() + { + return (a1, a2) => + { + _actionResultValue = a1 + a2; + }; + } + + private static bool AreEqual(int a, int b) + { + return a == b; + } + + private static string TestString1(string a) + { + return "Received: " + a; + } + + private static void SetTestString1(string a) + { + _delMethodStringResultValue = a; + } + + private static int TestInt2(int a, int b) + { + return a+b; + } + + // Create a method for a delegate. + public static void DelegateMethod(string message) + { + _delMethodResultValue = message; + Console.WriteLine(message); + } + + delegate void Del(string message); + internal static string _delMethodResultValue; + private static Del CreateDelegateMethod() + { + // Instantiate the delegate. + Del handler = DelegateMethod; + return handler; + } + + delegate string Del2(string message); + internal static string _delMethodStringResultValue; + private static Del2 CreateDelegateMethodReturnString() + { + // Instantiate the delegate. + Del2 handler = TestString1; + return handler; + } + } public enum TestEnum : uint { From 1c65efdb27b1f7f5b47bf61218c685b6b166ea37 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 1 Feb 2021 06:45:57 +0100 Subject: [PATCH 10/19] Add multi cast tests --- .../JavaScript/DelegateTests.cs | 25 ++++++++++- .../JavaScript/HelperMarshal.cs | 43 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 11aa7a00cfc04f..3cf6aa404bb029 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -124,12 +124,35 @@ public static void MarshalDelegateMethodReturnString() Runtime.InvokeJS(@" var del = App.call_test_method (""CreateDelegateMethodReturnString"", [ ]); var res = del(""Hic sunt dracones""); - console.log(res); App.call_test_method (""SetTestString1"", [ res ]); "); Assert.Equal("Received: Hic sunt dracones", HelperMarshal._delMethodStringResultValue); } + [Fact] + public static void MarshalCustomMultiDelegateAcceptingString() + { + HelperMarshal._custMultiDelStringResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateCustomMultiDelegateAcceptingString"", [ ]); + del(""Moin""); + "); + + Assert.Equal(" Hello, Moin! GoodMorning, Moin!", HelperMarshal._custMultiDelStringResultValue); + } + + [Fact] + public static void MarshalCustomMultiActionAcceptingString() + { + HelperMarshal._custMultiActionStringResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateCustomMultiActionAcceptingString"", [ ]); + del(""MoinMoin""); + "); + + Assert.Equal(" Hello, MoinMoin! GoodMorning, MoinMoin!", HelperMarshal._custMultiActionStringResultValue); + } + } } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index 1774d0069bb6ba..b1fa912246c7fe 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -451,6 +451,49 @@ private static Del2 CreateDelegateMethodReturnString() return handler; } + static void Hello(string s) + { + _custMultiDelStringResultValue += $" Hello, {s}!"; + } + + static void GoodMorning(string s) + { + _custMultiDelStringResultValue += $" GoodMorning, {s}!"; + } + + delegate void CustomDelStr(string s); + internal static string _custMultiDelStringResultValue; + private static CustomDelStr CreateCustomMultiDelegateAcceptingString() + { + CustomDelStr hiDel, mornDel, multiDel; + hiDel = Hello; + mornDel = GoodMorning; + multiDel = hiDel + mornDel; + + return multiDel; + } + + static void HelloHello(string s) + { + _custMultiActionStringResultValue += $" Hello, {s}!"; + } + + static void GoodMorningMorning(string s) + { + _custMultiActionStringResultValue += $" GoodMorning, {s}!"; + } + + internal static string _custMultiActionStringResultValue; + private static Action CreateCustomMultiActionAcceptingString() + { + Action hiDel, mornDel, multiDel; + hiDel = HelloHello; + mornDel = GoodMorningMorning; + multiDel = hiDel + mornDel; + + return multiDel; + } + } public enum TestEnum : uint { From 019c6428649209a2503369933a9ead61c3eda840 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 1 Feb 2021 07:10:05 +0100 Subject: [PATCH 11/19] Add anon and lamda del test --- .../JavaScript/DelegateTests.cs | 25 +++++++++++++++++++ .../JavaScript/HelperMarshal.cs | 17 ++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 3cf6aa404bb029..359c3337300444 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -117,6 +117,31 @@ public static void MarshalDelegateMethod() Assert.Equal("Hic sunt dracones", HelperMarshal._delMethodResultValue); } + [Fact] + public static void MarshalAnonDelegateMethod() + { + HelperMarshal._delAnonMethodStringResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateDelegateAnonMethodReturnString"", [ ]); + del(""Hic sunt dracones""); + "); + + Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delAnonMethodStringResultValue); + } + + + [Fact] + public static void MarshalLambdaDelegateMethod() + { + HelperMarshal._delLambdaMethodStringResultValue = string.Empty; + Runtime.InvokeJS(@" + var del = App.call_test_method (""CreateDelegateLambdaMethodReturnString"", [ ]); + del(""Hic sunt dracones""); + "); + + Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delLambdaMethodStringResultValue); + } + [Fact] public static void MarshalDelegateMethodReturnString() { diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index b1fa912246c7fe..4499bf56a59fc1 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -430,7 +430,6 @@ private static int TestInt2(int a, int b) public static void DelegateMethod(string message) { _delMethodResultValue = message; - Console.WriteLine(message); } delegate void Del(string message); @@ -451,6 +450,22 @@ private static Del2 CreateDelegateMethodReturnString() return handler; } + internal static string _delAnonMethodStringResultValue; + private static Del CreateDelegateAnonMethodReturnString() + { + // Instantiate the delegate. + Del handler = delegate(string name) { _delAnonMethodStringResultValue = $"Notification received for: {name}"; }; + return handler; + } + + internal static string _delLambdaMethodStringResultValue; + private static Del CreateDelegateLambdaMethodReturnString() + { + // Instantiate the delegate. + Del handler = (string name) => { _delLambdaMethodStringResultValue = $"Notification received for: {name}"; }; + return handler; + } + static void Hello(string s) { _custMultiDelStringResultValue += $" Hello, {s}!"; From 7f964e990246990775a201f8f7fa1df6bbc8bb94 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 1 Feb 2021 11:49:39 +0100 Subject: [PATCH 12/19] Add tests for marshaling TypedArray from different delegates. --- .../JavaScript/DelegateTests.cs | 31 +++++++++++++++++++ .../JavaScript/HelperMarshal.cs | 14 +++++++++ 2 files changed, 45 insertions(+) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 359c3337300444..d810b79b8bc876 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -9,6 +9,13 @@ namespace System.Runtime.InteropServices.JavaScript.Tests { public static class DelegateTests { + private static Function _objectPrototype; + public static IEnumerable Object_Prototype() + { + _objectPrototype ??= new Function("return Object.prototype.toString;"); + yield return new object[] { _objectPrototype.Call() }; + } + [Fact] public static void MarshalFunction() { @@ -179,5 +186,29 @@ public static void MarshalCustomMultiActionAcceptingString() Assert.Equal(" Hello, MoinMoin! GoodMorning, MoinMoin!", HelperMarshal._custMultiActionStringResultValue); } + [Theory] + [MemberData(nameof(Object_Prototype))] + public static void MarshalFunctionAcceptingUint8Array(Function objectPrototype) + { + var clamped = new byte[10]; + HelperMarshal._funcActionBufferResultValue = Uint8Array.From(clamped); + Assert.Equal(10, HelperMarshal._funcActionBufferResultValue.Length); + Assert.NotEqual("[object Uint8ClampedArray]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + + Runtime.InvokeJS(@" + var buffer = new Uint8Array(50); + var del = App.call_test_method (""CreateFunctionAcceptingUint8Array"", [ ]); + var setAction = del(buffer); + setAction(buffer); + "); + + Assert.Equal(50, HelperMarshal._funcActionBufferResultValue.Length); + Assert.Equal(HelperMarshal._funcActionBufferResultLengthValue, HelperMarshal._funcActionBufferResultValue.Length); + Assert.NotEqual("[object Uint8ClampedArray]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + + } + } } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index 4499bf56a59fc1..3f826b2862e291 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -509,6 +509,20 @@ private static Action CreateCustomMultiActionAcceptingString() return multiDel; } + internal static Uint8Array _funcActionBufferResultValue; + internal static int _funcActionBufferResultLengthValue; + private static Func> CreateFunctionAcceptingUint8Array() + { + return (buffer) => + { + _funcActionBufferResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + } public enum TestEnum : uint { From 5571af179ffd619999787a3aa2a38e509797eff8 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 05:39:19 +0100 Subject: [PATCH 13/19] Address review comment. Remove unused variable argsroot. --- src/mono/wasm/runtime/binding_support.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index 851db381884e6a..4617772d64bbe9 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -1458,7 +1458,7 @@ var BindingSupportLib = { throw new Error("The delegate target that is being invoked is no longer available. Please check if it has been prematurely GC'd."); } - var [delegateRoot, argsRoot] = MONO.mono_wasm_new_roots ([this.extract_mono_obj (delegate_obj), undefined]); + var [delegateRoot] = MONO.mono_wasm_new_roots ([this.extract_mono_obj (delegate_obj)]); try { if (typeof delegate_obj.__mono_delegate_invoke__ === "undefined") delegate_obj.__mono_delegate_invoke__ = this.mono_wasm_get_delegate_invoke(delegateRoot.value); @@ -1470,7 +1470,7 @@ var BindingSupportLib = { return this.call_method (delegate_obj.__mono_delegate_invoke__, delegateRoot.value, delegate_obj.__mono_delegate_invoke_sig__, js_args); } finally { - MONO.mono_wasm_release_roots (delegateRoot, argsRoot); + MONO.mono_wasm_release_roots (delegateRoot); } }, From 823b67c18e1da457b0de0e27b24327f2e56099c9 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 06:02:54 +0100 Subject: [PATCH 14/19] Remove extra assert as per review --- .../System/Runtime/InteropServices/JavaScript/DelegateTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index d810b79b8bc876..28967c4497ec8e 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -193,7 +193,6 @@ public static void MarshalFunctionAcceptingUint8Array(Function objectPrototype) var clamped = new byte[10]; HelperMarshal._funcActionBufferResultValue = Uint8Array.From(clamped); Assert.Equal(10, HelperMarshal._funcActionBufferResultValue.Length); - Assert.NotEqual("[object Uint8ClampedArray]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); Runtime.InvokeJS(@" From 28db172b3cfef6e5c994ded60417f60b85c5c398 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 06:03:34 +0100 Subject: [PATCH 15/19] Address review of switched expected --- .../Runtime/InteropServices/JavaScript/DelegateTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 28967c4497ec8e..a03cfccbfa8314 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -203,11 +203,8 @@ public static void MarshalFunctionAcceptingUint8Array(Function objectPrototype) "); Assert.Equal(50, HelperMarshal._funcActionBufferResultValue.Length); - Assert.Equal(HelperMarshal._funcActionBufferResultLengthValue, HelperMarshal._funcActionBufferResultValue.Length); - Assert.NotEqual("[object Uint8ClampedArray]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + Assert.Equal(HelperMarshal._funcActionBufferResultValue.Length, HelperMarshal._funcActionBufferResultLengthValue); Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); - } - } } From 58548c6aecb1a8a0205f0dea1651b42e3c31e5a1 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 06:20:59 +0100 Subject: [PATCH 16/19] As per review comment Rename all Marshal method names to Invoke --- .../JavaScript/DelegateTests.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index a03cfccbfa8314..e9b66b056487d8 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -17,7 +17,7 @@ public static IEnumerable Object_Prototype() } [Fact] - public static void MarshalFunction() + public static void InvokeFunction() { HelperMarshal._functionResultValue = 0; HelperMarshal._i32Value = 0; @@ -33,7 +33,7 @@ public static void MarshalFunction() } [Fact] - public static void MarshalFunctionLooptyLoop() + public static void InvokeFunctionInLoopUsingConstanceValues() { HelperMarshal._functionResultValue = 0; HelperMarshal._i32Value = 0; @@ -53,7 +53,7 @@ public static void MarshalFunctionLooptyLoop() } [Fact] - public static void MarshalFunctionLooptyLoopIncrement() + public static void InvokeFunctionInLoopUsingIncrementedValues() { HelperMarshal._functionResultValue = 0; HelperMarshal._i32Value = 0; @@ -72,7 +72,7 @@ public static void MarshalFunctionLooptyLoopIncrement() } [Fact] - public static void MarshalFunctionReturnAction() + public static void InvokeActionTReturnedByInvokingFuncT() { HelperMarshal._functionActionResultValue = 0; HelperMarshal._functionActionResultValueOfAction = 0; @@ -88,7 +88,7 @@ public static void MarshalFunctionReturnAction() } [Fact] - public static void MarshalActionIntInt() + public static void InvokeActionIntInt() { HelperMarshal._actionResultValue = 0; @@ -101,7 +101,7 @@ public static void MarshalActionIntInt() } [Fact] - public static void MarshalActionFloatIntToIntInt() + public static void InvokeActionFloatIntToIntInt() { HelperMarshal._actionResultValue = 0; Runtime.InvokeJS(@" @@ -113,7 +113,7 @@ public static void MarshalActionFloatIntToIntInt() } [Fact] - public static void MarshalDelegateMethod() + public static void InvokeDelegateMethod() { HelperMarshal._delMethodResultValue = string.Empty; Runtime.InvokeJS(@" @@ -125,7 +125,7 @@ public static void MarshalDelegateMethod() } [Fact] - public static void MarshalAnonDelegateMethod() + public static void InvokeAnonDelegateMethod() { HelperMarshal._delAnonMethodStringResultValue = string.Empty; Runtime.InvokeJS(@" @@ -138,7 +138,7 @@ public static void MarshalAnonDelegateMethod() [Fact] - public static void MarshalLambdaDelegateMethod() + public static void InvokeLambdaDelegateMethod() { HelperMarshal._delLambdaMethodStringResultValue = string.Empty; Runtime.InvokeJS(@" @@ -150,7 +150,7 @@ public static void MarshalLambdaDelegateMethod() } [Fact] - public static void MarshalDelegateMethodReturnString() + public static void InvokeDelegateMethodReturnString() { HelperMarshal._delMethodStringResultValue = string.Empty; Runtime.InvokeJS(@" @@ -163,7 +163,7 @@ public static void MarshalDelegateMethodReturnString() } [Fact] - public static void MarshalCustomMultiDelegateAcceptingString() + public static void InvokeCustomMultiDelegateAcceptingString() { HelperMarshal._custMultiDelStringResultValue = string.Empty; Runtime.InvokeJS(@" @@ -175,7 +175,7 @@ public static void MarshalCustomMultiDelegateAcceptingString() } [Fact] - public static void MarshalCustomMultiActionAcceptingString() + public static void InvokeCustomMultiActionAcceptingString() { HelperMarshal._custMultiActionStringResultValue = string.Empty; Runtime.InvokeJS(@" @@ -188,7 +188,7 @@ public static void MarshalCustomMultiActionAcceptingString() [Theory] [MemberData(nameof(Object_Prototype))] - public static void MarshalFunctionAcceptingUint8Array(Function objectPrototype) + public static void InvokeFunctionAcceptingUint8Array(Function objectPrototype) { var clamped = new byte[10]; HelperMarshal._funcActionBufferResultValue = Uint8Array.From(clamped); From 81a375ababc7668eeeec3d3bf5fe76f4afef61fc Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 11:19:16 +0100 Subject: [PATCH 17/19] Add more array type tests for delegates. --- .../JavaScript/DelegateTests.cs | 43 ++++--- .../JavaScript/HelperMarshal.cs | 112 +++++++++++++++++- 2 files changed, 136 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index e9b66b056487d8..6a553d25c6ecec 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -10,11 +10,6 @@ namespace System.Runtime.InteropServices.JavaScript.Tests public static class DelegateTests { private static Function _objectPrototype; - public static IEnumerable Object_Prototype() - { - _objectPrototype ??= new Function("return Object.prototype.toString;"); - yield return new object[] { _objectPrototype.Call() }; - } [Fact] public static void InvokeFunction() @@ -186,25 +181,39 @@ public static void InvokeCustomMultiActionAcceptingString() Assert.Equal(" Hello, MoinMoin! GoodMorning, MoinMoin!", HelperMarshal._custMultiActionStringResultValue); } + public static IEnumerable ArrayType_TestData() + { + _objectPrototype ??= new Function("return Object.prototype.toString;"); + yield return new object[] { _objectPrototype.Call(), "Uint8Array", Uint8Array.From(new byte[10]) }; + yield return new object[] { _objectPrototype.Call(), "Uint8ClampedArray", Uint8ClampedArray.From(new byte[10]) }; + yield return new object[] { _objectPrototype.Call(), "Int8Array", Int8Array.From(new sbyte[10]) }; + yield return new object[] { _objectPrototype.Call(), "Uint16Array", Uint16Array.From(new ushort[10]) }; + yield return new object[] { _objectPrototype.Call(), "Int16Array", Int16Array.From(new short[10]) }; + yield return new object[] { _objectPrototype.Call(), "Uint32Array", Uint32Array.From(new uint[10]) }; + yield return new object[] { _objectPrototype.Call(), "Int32Array", Int32Array.From(new int[10]) }; + yield return new object[] { _objectPrototype.Call(), "Float32Array", Float32Array.From(new float[10]) }; + yield return new object[] { _objectPrototype.Call(), "Float64Array", Float64Array.From(new double[10]) }; + yield return new object[] { _objectPrototype.Call(), "Array", new Array(10) }; + } + [Theory] - [MemberData(nameof(Object_Prototype))] - public static void InvokeFunctionAcceptingUint8Array(Function objectPrototype) + [MemberData(nameof(ArrayType_TestData))] + public static void InvokeFunctionAcceptingArrayTypes(Function objectPrototype, string creator, JSObject arrayType ) { - var clamped = new byte[10]; - HelperMarshal._funcActionBufferResultValue = Uint8Array.From(clamped); - Assert.Equal(10, HelperMarshal._funcActionBufferResultValue.Length); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + HelperMarshal._funcActionBufferObjectResultValue = arrayType; + Assert.Equal(10, HelperMarshal._funcActionBufferObjectResultValue.Length); + Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); - Runtime.InvokeJS(@" - var buffer = new Uint8Array(50); - var del = App.call_test_method (""CreateFunctionAcceptingUint8Array"", [ ]); + Runtime.InvokeJS($@" + var buffer = new {creator}(50); + var del = App.call_test_method (""CreateFunctionAccepting{creator}"", [ ]); var setAction = del(buffer); setAction(buffer); "); - Assert.Equal(50, HelperMarshal._funcActionBufferResultValue.Length); - Assert.Equal(HelperMarshal._funcActionBufferResultValue.Length, HelperMarshal._funcActionBufferResultLengthValue); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(HelperMarshal._funcActionBufferResultValue)); + Assert.Equal(50, HelperMarshal._funcActionBufferObjectResultValue.Length); + Assert.Equal(HelperMarshal._funcActionBufferObjectResultValue.Length, HelperMarshal._funcActionBufferResultLengthValue); + Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); } } } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index 3f826b2862e291..a5fbed700e2290 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -509,13 +509,121 @@ private static Action CreateCustomMultiActionAcceptingString() return multiDel; } - internal static Uint8Array _funcActionBufferResultValue; + internal static JSObject _funcActionBufferObjectResultValue; internal static int _funcActionBufferResultLengthValue; + private static Func> CreateFunctionAcceptingUint8ClampedArray() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + private static Func> CreateFunctionAcceptingUint8Array() { return (buffer) => { - _funcActionBufferResultValue = buffer; + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingInt8Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingUint16Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingInt16Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingUint32Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingInt32Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingFloat32Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingFloat64Array() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; + return (i1) => + { + _funcActionBufferResultLengthValue = i1.Length; + }; + }; + } + + private static Func> CreateFunctionAcceptingArray() + { + return (buffer) => + { + _funcActionBufferObjectResultValue = buffer; return (i1) => { _funcActionBufferResultLengthValue = i1.Length; From a19b8cad947dc6ac4a7ce3cb49fa8f0a3850f474 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 2 Feb 2021 11:50:11 +0100 Subject: [PATCH 18/19] Combine Delegate tests and Multi Cast delegate tests --- .../JavaScript/DelegateTests.cs | 62 +++++++------------ .../JavaScript/HelperMarshal.cs | 52 +++++++--------- 2 files changed, 44 insertions(+), 70 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index 6a553d25c6ecec..2414a6ca17ccd4 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -119,31 +119,6 @@ public static void InvokeDelegateMethod() Assert.Equal("Hic sunt dracones", HelperMarshal._delMethodResultValue); } - [Fact] - public static void InvokeAnonDelegateMethod() - { - HelperMarshal._delAnonMethodStringResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateAnonMethodReturnString"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delAnonMethodStringResultValue); - } - - - [Fact] - public static void InvokeLambdaDelegateMethod() - { - HelperMarshal._delLambdaMethodStringResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateLambdaMethodReturnString"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delLambdaMethodStringResultValue); - } - [Fact] public static void InvokeDelegateMethodReturnString() { @@ -157,28 +132,33 @@ public static void InvokeDelegateMethodReturnString() Assert.Equal("Received: Hic sunt dracones", HelperMarshal._delMethodStringResultValue); } - [Fact] - public static void InvokeCustomMultiDelegateAcceptingString() + [Theory] + [InlineData("CreateCustomMultiCastDelegate_VoidString", "Moin")] + [InlineData("CreateMultiCastAction_VoidString", "MoinMoin")] + public static void InvokeMultiCastDelegate_VoidString(string creator, string testStr) { - HelperMarshal._custMultiDelStringResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateCustomMultiDelegateAcceptingString"", [ ]); - del(""Moin""); + HelperMarshal._delegateCallResult = string.Empty; + Runtime.InvokeJS($@" + var del = App.call_test_method (""{creator}"", [ ]); + del(""{testStr}""); "); - - Assert.Equal(" Hello, Moin! GoodMorning, Moin!", HelperMarshal._custMultiDelStringResultValue); + Assert.Equal($" Hello, {testStr}! GoodMorning, {testStr}!", HelperMarshal._delegateCallResult); } - - [Fact] - public static void InvokeCustomMultiActionAcceptingString() + + [Theory] + [InlineData("CreateDelegateFromAnonymousMethod_VoidString")] + [InlineData("CreateDelegateFromLambda_VoidString")] + [InlineData("CreateDelegateFromMethod_VoidString")] + [InlineData("CreateActionT_VoidString")] + public static void InvokeDelegate_VoidString(string creator) { - HelperMarshal._custMultiActionStringResultValue = string.Empty; - Runtime.InvokeJS(@" - var del = App.call_test_method (""CreateCustomMultiActionAcceptingString"", [ ]); - del(""MoinMoin""); + HelperMarshal._delegateCallResult = string.Empty; + var s = Runtime.InvokeJS($@" + var del = App.call_test_method (""{creator}"", [ ]); + del(""Hic sunt dracones""); "); - Assert.Equal(" Hello, MoinMoin! GoodMorning, MoinMoin!", HelperMarshal._custMultiActionStringResultValue); + Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delegateCallResult); } public static IEnumerable ArrayType_TestData() diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs index a5fbed700e2290..8c2e8fe5527fe0 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs @@ -421,11 +421,6 @@ private static void SetTestString1(string a) _delMethodStringResultValue = a; } - private static int TestInt2(int a, int b) - { - return a+b; - } - // Create a method for a delegate. public static void DelegateMethod(string message) { @@ -450,35 +445,45 @@ private static Del2 CreateDelegateMethodReturnString() return handler; } - internal static string _delAnonMethodStringResultValue; - private static Del CreateDelegateAnonMethodReturnString() + internal static string _delegateCallResult; + private static Del CreateDelegateFromAnonymousMethod_VoidString() { // Instantiate the delegate. - Del handler = delegate(string name) { _delAnonMethodStringResultValue = $"Notification received for: {name}"; }; + Del handler = delegate(string name) { _delegateCallResult = $"Notification received for: {name}"; }; return handler; } - internal static string _delLambdaMethodStringResultValue; - private static Del CreateDelegateLambdaMethodReturnString() + private static Del CreateDelegateFromLambda_VoidString() + { + // Instantiate the delegate. + Del handler = (string name) => { _delegateCallResult = $"Notification received for: {name}"; }; + return handler; + } + + public static void DelegateMethod_VoidString(string name) => _delegateCallResult = $"Notification received for: {name}"; + + private static Del CreateDelegateFromMethod_VoidString() { // Instantiate the delegate. - Del handler = (string name) => { _delLambdaMethodStringResultValue = $"Notification received for: {name}"; }; + Del handler = DelegateMethod_VoidString; return handler; } + private static Action CreateActionT_VoidString() + => (string name) => _delegateCallResult = $"Notification received for: {name}"; + static void Hello(string s) { - _custMultiDelStringResultValue += $" Hello, {s}!"; + _delegateCallResult += $" Hello, {s}!"; } static void GoodMorning(string s) { - _custMultiDelStringResultValue += $" GoodMorning, {s}!"; + _delegateCallResult += $" GoodMorning, {s}!"; } delegate void CustomDelStr(string s); - internal static string _custMultiDelStringResultValue; - private static CustomDelStr CreateCustomMultiDelegateAcceptingString() + private static CustomDelStr CreateCustomMultiCastDelegate_VoidString() { CustomDelStr hiDel, mornDel, multiDel; hiDel = Hello; @@ -488,22 +493,11 @@ private static CustomDelStr CreateCustomMultiDelegateAcceptingString() return multiDel; } - static void HelloHello(string s) - { - _custMultiActionStringResultValue += $" Hello, {s}!"; - } - - static void GoodMorningMorning(string s) - { - _custMultiActionStringResultValue += $" GoodMorning, {s}!"; - } - - internal static string _custMultiActionStringResultValue; - private static Action CreateCustomMultiActionAcceptingString() + private static Action CreateMultiCastAction_VoidString() { Action hiDel, mornDel, multiDel; - hiDel = HelloHello; - mornDel = GoodMorningMorning; + hiDel = Hello; + mornDel = GoodMorning; multiDel = hiDel + mornDel; return multiDel; From b1f78ad66454b37fa7a560e898ee187022b82a4b Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 10 Feb 2021 06:11:11 +0100 Subject: [PATCH 19/19] Fix accessor after merge conflict --- .../InteropServices/JavaScript/Runtime.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index b18dbe1350fe25..4c2a55c745810c 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -75,7 +75,7 @@ public static void DumpAotProfileData (ref byte buf, int len, string extraArg) Interop.Runtime.DumpAotProfileData(ref buf, len, extraArg); } - private static int BindJSObject(int jsId, bool ownsHandle, int mappedType) + public static int BindJSObject(int jsId, bool ownsHandle, int mappedType) { WeakReference? reference; lock (_boundObjects) @@ -99,7 +99,7 @@ private static int BindJSObject(int jsId, bool ownsHandle, int mappedType) return reference.Target is JSObject target ? target.Int32Handle : 0; } - private static int BindCoreCLRObject(int jsId, int gcHandle) + public static int BindCoreCLRObject(int jsId, int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; JSObject? obj; @@ -157,7 +157,7 @@ internal static bool ReleaseJSObject(JSObject objToRelease) return true; } - private static void UnBindRawJSObjectAndFree(int gcHandle) + public static void UnBindRawJSObjectAndFree(int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; JSObject? obj = h.Target as JSObject; @@ -171,27 +171,27 @@ private static void UnBindRawJSObjectAndFree(int gcHandle) } } - private static object CreateTaskSource(int jsId) + public static object CreateTaskSource(int jsId) { return new TaskCompletionSource(); } - private static void SetTaskSourceResult(TaskCompletionSource tcs, object result) + public static void SetTaskSourceResult(TaskCompletionSource tcs, object result) { tcs.SetResult(result); } - private static void SetTaskSourceFailure(TaskCompletionSource tcs, string reason) + public static void SetTaskSourceFailure(TaskCompletionSource tcs, string reason) { tcs.SetException(new JSException(reason)); } - private static int GetTaskAndBind(TaskCompletionSource tcs, int jsId) + public static int GetTaskAndBind(TaskCompletionSource tcs, int jsId) { return BindExistingObject(tcs.Task, jsId); } - private static int BindExistingObject(object rawObj, int jsId) + public static int BindExistingObject(object rawObj, int jsId) { JSObject? jsObject; if (rawObj is Delegate dele) @@ -219,7 +219,7 @@ private static int BindExistingObject(object rawObj, int jsId) return jsObject.Int32Handle; } - private static int GetJSObjectId(object rawObj) + public static int GetJSObjectId(object rawObj) { JSObject? jsObject; if (rawObj is Delegate dele) @@ -239,7 +239,7 @@ private static int GetJSObjectId(object rawObj) return jsObject?.JSHandle ?? -1; } - private static object? GetDotNetObject(int gcHandle) + public static object? GetDotNetObject(int gcHandle) { GCHandle h = (GCHandle)(IntPtr)gcHandle; @@ -247,7 +247,7 @@ private static int GetJSObjectId(object rawObj) js.GetWrappedObject() ?? h.Target : h.Target; } - private static bool IsSimpleArray(object a) + public static bool IsSimpleArray(object a) { return a is System.Array arr && arr.Rank == 1 && arr.GetLowerBound(0) == 0; } @@ -338,7 +338,7 @@ public static string GetCallSignature(IntPtr methodHandle, object objForRuntimeT return new string(res); } - private static void SetupJSContinuation(Task task, JSObject continuationObj) + public static void SetupJSContinuation(Task task, JSObject continuationObj) { if (task.IsCompleted) Complete(); @@ -405,12 +405,12 @@ void Complete() return null; } - private static string ObjectToString(object o) + public static string ObjectToString(object o) { return o.ToString() ?? string.Empty; } - private static double GetDateValue(object dtv) + public static double GetDateValue(object dtv) { if (dtv == null) throw new ArgumentNullException(nameof(dtv)); @@ -423,18 +423,18 @@ private static double GetDateValue(object dtv) return new DateTimeOffset(dt).ToUnixTimeMilliseconds(); } - private static DateTime CreateDateTime(double ticks) + public static DateTime CreateDateTime(double ticks) { DateTimeOffset unixTime = DateTimeOffset.FromUnixTimeMilliseconds((long)ticks); return unixTime.DateTime; } - private static Uri CreateUri(string uri) + public static Uri CreateUri(string uri) { return new Uri(uri); } - private static bool SafeHandleAddRef(SafeHandle safeHandle) + public static bool SafeHandleAddRef(SafeHandle safeHandle) { bool _addRefSucceeded = false; #if DEBUG_HANDLE @@ -466,7 +466,7 @@ private static bool SafeHandleAddRef(SafeHandle safeHandle) return _addRefSucceeded; } - private static void SafeHandleRelease(SafeHandle safeHandle) + public static void SafeHandleRelease(SafeHandle safeHandle) { safeHandle.DangerousRelease(); #if DEBUG_HANDLE @@ -479,7 +479,7 @@ private static void SafeHandleRelease(SafeHandle safeHandle) #endif } - private static void SafeHandleReleaseByHandle(int jsId) + public static void SafeHandleReleaseByHandle(int jsId) { #if DEBUG_HANDLE Debug.WriteLine($"SafeHandleReleaseByHandle: {jsId}");