JavascriptSet.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. class JavascriptSet : public DynamicObject
  9. {
  10. public:
  11. typedef MapOrSetDataNode<Var> SetDataNode;
  12. typedef MapOrSetDataList<Var> SetDataList;
  13. typedef JsUtil::BaseDictionary<Var, SetDataNode*, Recycler, PowerOf2SizePolicy, SameValueZeroComparer> ComplexVarDataSet;
  14. typedef JsUtil::BaseDictionary<Var, SetDataNode*, Recycler> SimpleVarDataSet;
  15. private:
  16. enum class SetKind : uint8
  17. {
  18. // An EmptySet is a set containing no elements
  19. EmptySet,
  20. // An IntSet is a set containing only int elements
  21. //
  22. // Adding any TaggedInt or JavascriptNumber that can be represented as a TaggedInt
  23. // will succeed and be stored as an int32 in the set, EXCEPT for the value -1
  24. // Adding any other value will cause the set to be promoted to a SimpleVarSet or ComplexVarSet,
  25. // depending on the value being added
  26. //
  27. // Deleting any element will also cause the set to be promoted to a SimpleVarSet
  28. IntSet,
  29. // A SimpleVarSet is a set containing only Vars which are comparable by pointer, and don't require
  30. // value comparison
  31. //
  32. // Addition of a Var that is not comparable by pointer value causes the set to be promoted to a ComplexVarSet
  33. SimpleVarSet,
  34. // A ComplexVarSet is a set containing Vars for which we must inspect the values to do a comparison
  35. // This includes Strings and (sometimes) JavascriptNumbers
  36. ComplexVarSet
  37. };
  38. Field(SetDataList) list;
  39. union SetUnion
  40. {
  41. Field(SimpleVarDataSet*) simpleVarSet;
  42. Field(ComplexVarDataSet*) complexVarSet;
  43. Field(BVSparse<Recycler>*) intSet;
  44. SetUnion() {}
  45. };
  46. Field(SetUnion) u;
  47. Field(SetKind) kind = SetKind::EmptySet;
  48. DEFINE_VTABLE_CTOR_MEMBER_INIT(JavascriptSet, DynamicObject, list);
  49. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JavascriptSet);
  50. template <typename T>
  51. T* CreateVarSetFromList(uint initialCapacity);
  52. void PromoteToSimpleVarSet();
  53. void PromoteToComplexVarSet();
  54. void AddToEmptySet(Var value);
  55. bool TryAddToIntSet(Var value);
  56. bool TryAddToSimpleVarSet(Var value);
  57. void AddToComplexVarSet(Var value);
  58. bool IsInIntSet(Var value);
  59. template <bool isComplex>
  60. bool DeleteFromVarSet(Var value);
  61. bool DeleteFromSimpleVarSet(Var value);
  62. public:
  63. JavascriptSet(DynamicType* type);
  64. static JavascriptSet* New(ScriptContext* scriptContext);
  65. void Add(Var value);
  66. void Clear();
  67. bool Delete(Var value);
  68. bool Has(Var value);
  69. int Size();
  70. SetDataList::Iterator GetIterator();
  71. virtual BOOL GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
  72. class EntryInfo
  73. {
  74. public:
  75. static FunctionInfo NewInstance;
  76. static FunctionInfo Add;
  77. static FunctionInfo Clear;
  78. static FunctionInfo Delete;
  79. static FunctionInfo ForEach;
  80. static FunctionInfo Has;
  81. static FunctionInfo SizeGetter;
  82. static FunctionInfo Entries;
  83. static FunctionInfo Values;
  84. static FunctionInfo GetterSymbolSpecies;
  85. };
  86. static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...);
  87. static Var EntryAdd(RecyclableObject* function, CallInfo callInfo, ...);
  88. static Var EntryClear(RecyclableObject* function, CallInfo callInfo, ...);
  89. static Var EntryDelete(RecyclableObject* function, CallInfo callInfo, ...);
  90. static Var EntryForEach(RecyclableObject* function, CallInfo callInfo, ...);
  91. static Var EntryHas(RecyclableObject* function, CallInfo callInfo, ...);
  92. static Var EntrySizeGetter(RecyclableObject* function, CallInfo callInfo, ...);
  93. static Var EntryEntries(RecyclableObject* function, CallInfo callInfo, ...);
  94. static Var EntryValues(RecyclableObject* function, CallInfo callInfo, ...);
  95. static Var EntryGetterSymbolSpecies(RecyclableObject* function, CallInfo callInfo, ...);
  96. #if ENABLE_TTD
  97. public:
  98. virtual void MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor) override;
  99. virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
  100. virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
  101. static JavascriptSet* CreateForSnapshotRestore(ScriptContext* ctx);
  102. #endif
  103. };
  104. template <> inline bool VarIsImpl<JavascriptSet>(RecyclableObject* obj)
  105. {
  106. return JavascriptOperators::GetTypeId(obj) == TypeIds_Set;
  107. }
  108. }