1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QV4PROPERTYKEY_H
4#define QV4PROPERTYKEY_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <private/qv4global_p.h>
18#include <private/qv4staticvalue_p.h>
19#include <QtCore/qhashfunctions.h>
20
21QT_BEGIN_NAMESPACE
22
23class QString;
24
25namespace QV4 {
26
27struct PropertyKey
28{
29private:
30 // Property keys are Strings, Symbols or unsigned integers.
31 // For convenience we derive them from Values, allowing us to store them
32 // on the JS stack
33 //
34 // They do however behave somewhat different than a Value:
35 // * If the key is a String, the pointer to the string is stored in the identifier
36 // table and thus unique.
37 // * If the key is a Symbol it simply points to the referenced symbol object
38 // * if the key is an array index (a uint < UINT_MAX), it's encoded as an
39 // integer value
40 QV4::StaticValue val;
41
42 inline bool isManaged() const { return val.isManaged(); }
43 inline quint32 value() const { return val.value(); }
44
45public:
46 static PropertyKey invalid()
47 {
48 PropertyKey key;
49 key.val = StaticValue::undefinedValue();
50 return key;
51 }
52
53 static PropertyKey fromArrayIndex(uint idx)
54 {
55 PropertyKey key;
56 key.val.setInt_32(idx);
57 return key;
58 }
59
60 bool isStringOrSymbol() const { return isManaged(); }
61 uint asArrayIndex() const
62 {
63 Q_ASSERT(isArrayIndex());
64 return value();
65 }
66
67 bool isArrayIndex() const { return val.isInteger(); }
68 bool isValid() const { return !val.isUndefined(); }
69
70 // We cannot #include the declaration of Heap::StringOrSymbol here.
71 // Therefore we do some gymnastics to enforce the type safety.
72
73 template<typename StringOrSymbol = Heap::StringOrSymbol>
74 static PropertyKey fromStringOrSymbol(StringOrSymbol *b)
75 {
76 static_assert(std::is_base_of_v<Heap::StringOrSymbol, StringOrSymbol>);
77 PropertyKey key;
78 key.val.setM(b);
79 Q_ASSERT(key.isManaged());
80 return key;
81 }
82
83 template<typename StringOrSymbol = Heap::StringOrSymbol>
84 StringOrSymbol *asStringOrSymbol() const
85 {
86 static_assert(std::is_base_of_v<Heap::StringOrSymbol, StringOrSymbol>);
87 if (!isManaged())
88 return nullptr;
89 return static_cast<StringOrSymbol *>(val.m());
90 }
91
92 Q_QML_PRIVATE_EXPORT bool isString() const;
93 Q_QML_PRIVATE_EXPORT bool isSymbol() const;
94 bool isCanonicalNumericIndexString() const;
95
96 Q_QML_PRIVATE_EXPORT QString toQString() const;
97 Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e);
98 quint64 id() const { return val._val; }
99 static PropertyKey fromId(quint64 id) {
100 PropertyKey key; key.val._val = id; return key;
101 }
102
103 enum FunctionNamePrefix {
104 None,
105 Getter,
106 Setter
107 };
108 Heap::String *asFunctionName(ExecutionEngine *e, FunctionNamePrefix prefix) const;
109
110 bool operator ==(const PropertyKey &other) const { return val._val == other.val._val; }
111 bool operator !=(const PropertyKey &other) const { return val._val != other.val._val; }
112 bool operator <(const PropertyKey &other) const { return val._val < other.val._val; }
113 friend size_t qHash(const PropertyKey &key, size_t seed = 0) { return qHash(key: key.val._val, seed); }
114};
115
116}
117
118QT_END_NAMESPACE
119
120#endif
121

source code of qtdeclarative/src/qml/jsruntime/qv4propertykey_p.h