Przeglądaj źródła

Fix NRE in BuildTargetBinderDelegate (#2116)

* remove unnecessary reflection
* add BoundFunction interop test
David Rettenbacher 1 miesiąc temu
rodzic
commit
4d9be48923

+ 44 - 0
Jint.Tests/Runtime/InteropTests.cs

@@ -3824,4 +3824,48 @@ try {
         Assert.Equal(values[0], found1);
         Assert.Equal(values[1], found2);
     }
+
+    [Fact]
+    public void CanCallBoundJavascriptFunctionFromDotnet()
+    {
+        var ticker = new Ticker();
+        _engine.SetValue("ticker", ticker);
+
+        var counter = (double) _engine.Evaluate("""
+            function tickHandler() {
+                counter++;
+            }
+
+            let counter = 0;
+            const dummyThisObject = {};
+
+            // bind javascript function to new this-object
+            const tickerHandlerBinding = tickHandler.bind(dummyThisObject);
+            
+            // register it with .NET
+            ticker.add_Ticked(tickerHandlerBinding);
+            ticker.Tick();
+
+            // unregister it
+            ticker.remove_Ticked(tickerHandlerBinding);
+            ticker.Tick();
+
+            // return counter as result
+            counter;
+            """).ToObject();
+
+        ticker.Tick();
+        counter.Should().Be(1);
+    }
+
+    internal class Ticker
+    {
+        public event EventHandler Ticked;
+
+        public void Tick()
+        {
+            Ticked?.Invoke(this, EventArgs.Empty);
+        }
+    }
+
 }

+ 1 - 3
Jint/Runtime/Interop/DefaultTypeConverter.cs

@@ -280,12 +280,10 @@ public class DefaultTypeConverter : ITypeConverter
         [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type delegateType,
         JsCallDelegate function)
     {
-        var targetMethod = function.Target!.GetType().GetMethod("Call", BindingFlags.Instance | BindingFlags.NonPublic)!;
-
         // Parameter for the target object
         var targetParam = Expression.Parameter(typeof(object), "target");
 
-        var castedTarget = Expression.Convert(targetParam, targetMethod.DeclaringType!);
+        var castedTarget = Expression.Convert(targetParam, function.Target!.GetType());
 
         var innerDelegate = BuildDelegate(delegateType, function, castedTarget);