ClrFunctionInstance.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System.Runtime.CompilerServices;
  2. using System.Runtime.ExceptionServices;
  3. using Jint.Native;
  4. using Jint.Native.Function;
  5. using Jint.Runtime.Descriptors;
  6. namespace Jint.Runtime.Interop;
  7. /// <summary>
  8. /// Wraps a Clr method into a FunctionInstance
  9. /// </summary>
  10. public sealed class ClrFunctionInstance : FunctionInstance, IEquatable<ClrFunctionInstance>
  11. {
  12. internal readonly Func<JsValue, JsValue[], JsValue> _func;
  13. private readonly bool _bubbleExceptions;
  14. public ClrFunctionInstance(
  15. Engine engine,
  16. string name,
  17. Func<JsValue, JsValue[], JsValue> func,
  18. int length = 0,
  19. PropertyFlag lengthFlags = PropertyFlag.AllForbidden)
  20. : base(engine, engine.Realm, new JsString(name))
  21. {
  22. _func = func;
  23. _prototype = engine._originalIntrinsics.Function.PrototypeObject;
  24. _length = lengthFlags == PropertyFlag.AllForbidden
  25. ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length)
  26. : new PropertyDescriptor(JsNumber.Create(length), lengthFlags);
  27. _bubbleExceptions = _engine.Options.Interop.ExceptionHandler == InteropOptions._defaultExceptionHandler;
  28. }
  29. protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments) => _bubbleExceptions ? _func(thisObject, arguments) : CallSlow(thisObject, arguments);
  30. [MethodImpl(MethodImplOptions.NoInlining)]
  31. private JsValue CallSlow(JsValue thisObject, JsValue[] arguments)
  32. {
  33. try
  34. {
  35. return _func(thisObject, arguments);
  36. }
  37. catch (Exception e) when (e is not JavaScriptException)
  38. {
  39. if (_engine.Options.Interop.ExceptionHandler(e))
  40. {
  41. ExceptionHelper.ThrowJavaScriptException(_realm.Intrinsics.Error, e.Message);
  42. }
  43. else
  44. {
  45. ExceptionDispatchInfo.Capture(e).Throw();
  46. }
  47. return Undefined;
  48. }
  49. }
  50. public override bool Equals(JsValue? obj) => Equals(obj as ClrFunctionInstance);
  51. public bool Equals(ClrFunctionInstance? other)
  52. {
  53. if (ReferenceEquals(null, other))
  54. {
  55. return false;
  56. }
  57. if (ReferenceEquals(this, other))
  58. {
  59. return true;
  60. }
  61. if (_func == other._func)
  62. {
  63. return true;
  64. }
  65. return false;
  66. }
  67. }