FinalizationRegistryInstance.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System.Runtime.CompilerServices;
  2. using Jint.Native.Object;
  3. using Jint.Runtime;
  4. namespace Jint.Native.FinalizationRegistry;
  5. internal sealed record Cell(JsValue WeakRefTarget, JsValue HeldValue, JsValue? UnregisterToken);
  6. internal sealed class FinalizationRegistryInstance : ObjectInstance
  7. {
  8. private readonly Realm _realm;
  9. private readonly JobCallback _callable;
  10. private readonly ConditionalWeakTable<JsValue, List<Observer>> _cells = new();
  11. private readonly Dictionary<JsValue, List<Observer>> _byToken = new();
  12. public FinalizationRegistryInstance(Engine engine, Realm realm, ICallable cleanupCallback) : base(engine)
  13. {
  14. _realm = realm;
  15. _callable = engine._host.MakeJobCallBack(cleanupCallback);
  16. }
  17. public void CleanupFinalizationRegistry(ICallable? callback)
  18. {
  19. }
  20. public void AddCell(Cell cell)
  21. {
  22. var observer = new Observer(_callable);
  23. var observerList = _cells.GetOrCreateValue(cell.WeakRefTarget);
  24. observerList.Add(observer);
  25. if (cell.UnregisterToken is not null)
  26. {
  27. if (!_byToken.TryGetValue(cell.UnregisterToken, out var list))
  28. {
  29. _byToken[cell.UnregisterToken] = list = new List<Observer>();
  30. }
  31. list.Add(observer);
  32. }
  33. }
  34. public JsValue Remove(JsValue unregisterToken)
  35. {
  36. if (_byToken.TryGetValue(unregisterToken, out var list))
  37. {
  38. var any = list.Count > 0;
  39. list.Clear();
  40. return any;
  41. }
  42. return false;
  43. }
  44. private sealed class Observer
  45. {
  46. private readonly JobCallback _callable;
  47. public Observer(JobCallback callable)
  48. {
  49. _callable = callable;
  50. }
  51. ~Observer()
  52. {
  53. _callable.Callback.Call(Undefined);
  54. }
  55. }
  56. }