ClrFunctionInstance.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System.Runtime.ExceptionServices;
  2. using Jint.Native;
  3. using Jint.Native.Function;
  4. using Jint.Runtime.Descriptors;
  5. namespace Jint.Runtime.Interop
  6. {
  7. /// <summary>
  8. /// Wraps a Clr method into a FunctionInstance
  9. /// </summary>
  10. public sealed class ClrFunctionInstance : FunctionInstance, IEquatable<ClrFunctionInstance>
  11. {
  12. private readonly string? _name;
  13. internal readonly Func<JsValue, JsValue[], JsValue> _func;
  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, name != null ? new JsString(name) : null)
  21. {
  22. _name = name;
  23. _func = func;
  24. _prototype = engine._originalIntrinsics.Function.PrototypeObject;
  25. _length = lengthFlags == PropertyFlag.AllForbidden
  26. ? PropertyDescriptor.AllForbiddenDescriptor.ForNumber(length)
  27. : new PropertyDescriptor(JsNumber.Create(length), lengthFlags);
  28. }
  29. protected internal override JsValue Call(JsValue thisObject, JsValue[] arguments)
  30. {
  31. try
  32. {
  33. return _func(thisObject, arguments);
  34. }
  35. catch (Exception e) when (e is not JavaScriptException)
  36. {
  37. if (_engine.Options.Interop.ExceptionHandler(e))
  38. {
  39. ExceptionHelper.ThrowJavaScriptException(_realm.Intrinsics.Error, e.Message);
  40. }
  41. else
  42. {
  43. ExceptionDispatchInfo.Capture(e).Throw();
  44. }
  45. return Undefined;
  46. }
  47. }
  48. public override bool Equals(JsValue? obj)
  49. {
  50. return Equals(obj as ClrFunctionInstance);
  51. }
  52. public bool Equals(ClrFunctionInstance? 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 string ToString() => "function " + _name + "() { [native code] }";
  69. }
  70. }