|
@@ -1,78 +1,81 @@
|
|
|
+using System.Runtime.CompilerServices;
|
|
|
using System.Runtime.ExceptionServices;
|
|
|
using Jint.Native;
|
|
|
using Jint.Native.Function;
|
|
|
using Jint.Runtime.Descriptors;
|
|
|
|
|
|
-namespace Jint.Runtime.Interop
|
|
|
+namespace Jint.Runtime.Interop;
|
|
|
+
|
|
|
+/// <summary>
|
|
|
+/// Wraps a Clr method into a FunctionInstance
|
|
|
+/// </summary>
|
|
|
+public sealed class ClrFunctionInstance : FunctionInstance, IEquatable<ClrFunctionInstance>
|
|
|
{
|
|
|
- /// <summary>
|
|
|
- /// Wraps a Clr method into a FunctionInstance
|
|
|
- /// </summary>
|
|
|
- public sealed class ClrFunctionInstance : FunctionInstance, IEquatable<ClrFunctionInstance>
|
|
|
+ internal readonly Func<JsValue, JsValue[], JsValue> _func;
|
|
|
+ private readonly bool _bubbleExceptions;
|
|
|
+
|
|
|
+ public ClrFunctionInstance(
|
|
|
+ Engine engine,
|
|
|
+ string name,
|
|
|
+ Func<JsValue, JsValue[], JsValue> func,
|
|
|
+ int length = 0,
|
|
|
+ PropertyFlag lengthFlags = PropertyFlag.AllForbidden)
|
|
|
+ : base(engine, engine.Realm, new JsString(name))
|
|
|
{
|
|
|
- internal readonly Func<JsValue, JsValue[], JsValue> _func;
|
|
|
+ _func = func;
|
|
|
|
|
|
- public ClrFunctionInstance(
|
|
|
- Engine engine,
|
|
|
- string name,
|
|
|
- Func<JsValue, JsValue[], JsValue> func,
|
|
|
- int length = 0,
|
|
|
- PropertyFlag lengthFlags = PropertyFlag.AllForbidden)
|
|
|
- : base(engine, engine.Realm, new JsString(name))
|
|
|
- {
|
|
|
- _func = func;
|
|
|
+ _prototype = engine._originalIntrinsics.Function.PrototypeObject;
|
|
|
|
|
|
- _prototype = engine._originalIntrinsics.Function.PrototypeObject;
|
|
|
+ _length = lengthFlags == PropertyFlag.AllForbidden
|
|
|
+ ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length)
|
|
|
+ : new PropertyDescriptor(JsNumber.Create(length), lengthFlags);
|
|
|
|
|
|
- _length = lengthFlags == PropertyFlag.AllForbidden
|
|
|
- ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length)
|
|
|
- : new PropertyDescriptor(JsNumber.Create(length), lengthFlags);
|
|
|
- }
|
|
|
+ _bubbleExceptions = _engine.Options.Interop.ExceptionHandler == InteropOptions._defaultExceptionHandler;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments) => _bubbleExceptions ? _func(thisObject, arguments) : CallSlow(thisObject, arguments);
|
|
|
|
|
|
- protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments)
|
|
|
+ [MethodImpl(MethodImplOptions.NoInlining)]
|
|
|
+ private JsValue CallSlow(JsValue thisObject, JsValue[] arguments)
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
+ return _func(thisObject, arguments);
|
|
|
+ }
|
|
|
+ catch (Exception e) when (e is not JavaScriptException)
|
|
|
+ {
|
|
|
+ if (_engine.Options.Interop.ExceptionHandler(e))
|
|
|
{
|
|
|
- return _func(thisObject, arguments);
|
|
|
+ ExceptionHelper.ThrowJavaScriptException(_realm.Intrinsics.Error, e.Message);
|
|
|
}
|
|
|
- catch (Exception e) when (e is not JavaScriptException)
|
|
|
+ else
|
|
|
{
|
|
|
- if (_engine.Options.Interop.ExceptionHandler(e))
|
|
|
- {
|
|
|
- ExceptionHelper.ThrowJavaScriptException(_realm.Intrinsics.Error, e.Message);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ExceptionDispatchInfo.Capture(e).Throw();
|
|
|
- }
|
|
|
-
|
|
|
- return Undefined;
|
|
|
+ ExceptionDispatchInfo.Capture(e).Throw();
|
|
|
}
|
|
|
+
|
|
|
+ return Undefined;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool Equals(JsValue? obj) => Equals(obj as ClrFunctionInstance);
|
|
|
|
|
|
- public override bool Equals(JsValue? obj)
|
|
|
+ public bool Equals(ClrFunctionInstance? other)
|
|
|
+ {
|
|
|
+ if (ReferenceEquals(null, other))
|
|
|
{
|
|
|
- return Equals(obj as ClrFunctionInstance);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- public bool Equals(ClrFunctionInstance? other)
|
|
|
+ if (ReferenceEquals(this, other))
|
|
|
{
|
|
|
- if (ReferenceEquals(null, other))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (ReferenceEquals(this, other))
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- if (_func == other._func)
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- return false;
|
|
|
+ if (_func == other._func)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
}
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|