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_TupleType_h
8 #define vm_TupleType_h
9 
10 #include <cstdint>
11 #include <functional>
12 #include "vm/JSContext.h"
13 #include "vm/NativeObject.h"
14 
15 namespace JS {
16 
17 class TupleType final : public js::NativeObject {
18  public:
19   static const js::ClassSpec classSpec_;
20   static const JSClass class_;
21   static const JSClass protoClass_;
22 
23  public:
24   static TupleType* create(JSContext* cx, uint32_t length,
25                            const Value* elements);
26 
27   static TupleType* createUninitialized(JSContext* cx, uint32_t initialLength);
28 
29   static TupleType* createUnchecked(JSContext* cx, js::HandleArrayObject aObj);
30 
31   bool initializeNextElement(JSContext* cx, HandleValue elt);
32   void finishInitialization(JSContext* cx);
33   static js::Shape* getInitialShape(JSContext* cx);
34 
35   bool getOwnProperty(HandleId id, MutableHandleValue vp) const;
length()36   inline uint32_t length() const { return getElementsHeader()->length; }
37 
38   // Methods defined on Tuple.prototype
39   [[nodiscard]] static bool lengthAccessor(JSContext* cx, unsigned argc,
40                                            Value* vp);
41 
42   // Comparison functions
43   static bool sameValueZero(JSContext* cx, TupleType* lhs, TupleType* rhs,
44                             bool* equal);
45   static bool sameValue(JSContext* cx, TupleType* lhs, TupleType* rhs,
46                         bool* equal);
47 
48   using ElementHasher = std::function<js::HashNumber(const Value& child)>;
49   js::HashNumber hash(const ElementHasher& hasher) const;
50 
51   bool ensureAtomized(JSContext* cx);
isAtomized()52   bool isAtomized() const { return getElementsHeader()->tupleIsAtomized(); }
53 
54   // This can be used to compare atomized tuples.
55   static bool sameValueZero(TupleType* lhs, TupleType* rhs);
56 
57   static TupleType& thisTupleValue(const Value& val);
58 
59  private:
60   template <bool Comparator(JSContext*, HandleValue, HandleValue, bool*)>
61   static bool sameValueWith(JSContext* cx, TupleType* lhs, TupleType* rhs,
62                             bool* equal);
63 };
64 
65 }  // namespace JS
66 
67 namespace js {
68 
69 extern JSString* TupleToSource(JSContext* cx, Handle<TupleType*> tup);
70 
71 bool IsTuple(const Value& v);
72 
73 extern bool tuple_toReversed(JSContext* cx, unsigned argc, Value* vp);
74 extern bool tuple_with(JSContext* cx, unsigned argc, Value* vp);
75 extern bool tuple_slice(JSContext* cx, unsigned argc, Value* vp);
76 extern bool tuple_is_tuple(JSContext* cx, unsigned argc, Value* vp);
77 extern bool tuple_value_of(JSContext* cx, unsigned argc, Value* vp);
78 extern bool tuple_of(JSContext* cx, unsigned argc, Value* vp);
79 extern bool tuple_construct(JSContext* cx, unsigned argc, Value* vp);
80 
81 }  // namespace js
82 
83 #endif
84