MapInstance.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using System.Diagnostics.CodeAnalysis;
  2. using System.Runtime.CompilerServices;
  3. using Jint.Native.Object;
  4. using Jint.Runtime;
  5. using Jint.Runtime.Descriptors;
  6. namespace Jint.Native.Map;
  7. public sealed class MapInstance : ObjectInstance
  8. {
  9. private readonly Realm _realm;
  10. internal readonly OrderedDictionary<JsValue, JsValue> _map;
  11. public MapInstance(Engine engine, Realm realm) : base(engine)
  12. {
  13. _realm = realm;
  14. _map = new OrderedDictionary<JsValue, JsValue>(SameValueZeroComparer.Instance);
  15. }
  16. public override PropertyDescriptor GetOwnProperty(JsValue property)
  17. {
  18. if (property == CommonProperties.Size)
  19. {
  20. return new PropertyDescriptor(_map.Count, PropertyFlag.AllForbidden);
  21. }
  22. return base.GetOwnProperty(property);
  23. }
  24. protected override bool TryGetProperty(JsValue property, [NotNullWhen(true)] out PropertyDescriptor? descriptor)
  25. {
  26. if (property == CommonProperties.Size)
  27. {
  28. descriptor = new PropertyDescriptor(_map.Count, PropertyFlag.AllForbidden);
  29. return true;
  30. }
  31. return base.TryGetProperty(property, out descriptor);
  32. }
  33. internal void Clear()
  34. {
  35. _map.Clear();
  36. }
  37. internal bool Has(JsValue key)
  38. {
  39. return _map.ContainsKey(key);
  40. }
  41. internal bool MapDelete(JsValue key)
  42. {
  43. return _map.Remove(key);
  44. }
  45. internal void MapSet(JsValue key, JsValue value)
  46. {
  47. if (key is JsNumber number && number.IsNegativeZero())
  48. {
  49. key = JsNumber.PositiveZero;
  50. }
  51. _map[key] = value;
  52. }
  53. internal void ForEach(ICallable callable, JsValue thisArg)
  54. {
  55. var args = _engine._jsValueArrayPool.RentArray(3);
  56. args[2] = this;
  57. for (var i = 0; i < _map.Count; i++)
  58. {
  59. args[0] = _map[i];
  60. args[1] = _map.GetKey(i);
  61. callable.Call(thisArg, args);
  62. }
  63. _engine._jsValueArrayPool.ReturnArray(args);
  64. }
  65. internal JsValue MapGet(JsValue key)
  66. {
  67. if (!_map.TryGetValue(key, out var value))
  68. {
  69. return Undefined;
  70. }
  71. return value;
  72. }
  73. internal ObjectInstance Iterator()
  74. {
  75. return _realm.Intrinsics.MapIteratorPrototype.ConstructEntryIterator(this);
  76. }
  77. internal ObjectInstance Keys()
  78. {
  79. return _realm.Intrinsics.MapIteratorPrototype.ConstructKeyIterator(this);
  80. }
  81. internal ObjectInstance Values()
  82. {
  83. return _realm.Intrinsics.MapIteratorPrototype.ConstructValueIterator(this);
  84. }
  85. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  86. internal uint GetSize()
  87. {
  88. return (uint) _map.Count;
  89. }
  90. }