1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef vm_RecordType_h
8 #define vm_RecordType_h
9 
10 #include <cstdint>
11 #include <functional>
12 #include "js/TypeDecls.h"
13 #include "vm/ArrayObject.h"
14 #include "vm/NativeObject.h"
15 
16 #include "vm/Shape.h"
17 
18 namespace JS {
19 class RecordType;
20 }
21 
22 namespace js {
23 
24 extern JSString* RecordToSource(JSContext* cx, JS::RecordType* rec);
25 
26 }
27 
28 namespace JS {
29 
30 class RecordType final : public js::NativeObject {
31   friend JSString* js::RecordToSource(JSContext* cx, RecordType* rec);
32 
33  public:
34   enum {
35     INITIALIZED_LENGTH_SLOT = 0,
36     SORTED_KEYS_SLOT,
37     IS_ATOMIZED_SLOT,
38     SLOT_COUNT
39   };
40 
41   static const js::ClassSpec classSpec_;
42   static const JSClass class_;
43 
44   static RecordType* createUninitialized(JSContext* cx, uint32_t initialLength);
45   bool initializeNextProperty(JSContext* cx, Handle<PropertyKey> key,
46                               HandleValue value);
47   bool finishInitialization(JSContext* cx);
48   static js::Shape* getInitialShape(JSContext* cx);
49 
50   bool getOwnProperty(JSContext* cx, HandleId id, MutableHandleValue vp) const;
51 
52   static bool sameValueZero(JSContext* cx, RecordType* lhs, RecordType* rhs,
53                             bool* equal);
54   static bool sameValue(JSContext* cx, RecordType* lhs, RecordType* rhs,
55                         bool* equal);
56 
keys()57   js::ArrayObject* keys() const {
58     return &getFixedSlot(SORTED_KEYS_SLOT).toObject().as<js::ArrayObject>();
59   }
60 
61   using FieldHasher = std::function<js::HashNumber(const Value& child)>;
62   js::HashNumber hash(const FieldHasher& hasher);
63 
64   bool ensureAtomized(JSContext* cx);
isAtomized()65   bool isAtomized() const { return getFixedSlot(IS_ATOMIZED_SLOT).toBoolean(); }
66 
67   // This can be used to compare atomized records.
68   static bool sameValueZero(RecordType* lhs, RecordType* rhs);
69 
70  private:
71   template <bool Comparator(JSContext*, HandleValue, HandleValue, bool*)>
72   static bool sameValueWith(JSContext* cx, RecordType* lhs, RecordType* rhs,
73                             bool* equal);
74 };
75 
76 }  // namespace JS
77 
78 #endif
79