2
0

ClrFunction.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 JS function.
  9. /// </summary>
  10. public sealed class ClrFunction : Function, IEquatable<ClrFunction>
  11. {
  12. internal readonly JsCallDelegate _func;
  13. private readonly bool _bubbleExceptions;
  14. public ClrFunction(
  15. Engine engine,
  16. string name,
  17. JsCallDelegate func,
  18. int length = 0,
  19. PropertyFlag lengthFlags = PropertyFlag.AllForbidden)
  20. : base(engine, engine.Realm, JsString.CachedCreate(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 == Options.InteropOptions._defaultExceptionHandler;
  28. }
  29. protected internal override JsValue Call(JsValue thisObject, JsCallArguments arguments) => _bubbleExceptions ? _func(thisObject, arguments) : CallSlow(thisObject, arguments);
  30. [MethodImpl(MethodImplOptions.NoInlining)]
  31. private JsValue CallSlow(JsValue thisObject, JsCallArguments 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. Throw.JavaScriptException(_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? other) => Equals(other as ClrFunction);
  51. public override bool Equals(object? obj) => Equals(obj as ClrFunction);
  52. public bool Equals(ClrFunction? other)
  53. {
  54. if (ReferenceEquals(null, other))
  55. {
  56. return false;
  57. }
  58. if (ReferenceEquals(this, other))
  59. {
  60. return true;
  61. }
  62. if (_func == other._func)
  63. {
  64. return true;
  65. }
  66. return false;
  67. }
  68. public override int GetHashCode() => _func.GetHashCode();
  69. }