Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4identifiertable.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 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
// Qt-Security score:significant
4
#
include
"qv4identifiertable_p.h"
5
#
include
"qv4symbol_p.h"
6
#
include
<
private
/
qv4identifierhashdata_p
.
h
>
7
#
include
<
private
/
qprimefornumbits_p
.
h
>
8
9
QT_BEGIN_NAMESPACE
10
11
namespace
QV4
{
12
13
IdentifierTable
::
IdentifierTable
(
ExecutionEngine
*
engine
,
int
numBits
)
14
:
engine
(
engine
)
15
,
size
(0)
16
,
numBits
(
numBits
)
17
{
18
alloc
=
qPrimeForNumBits
(
numBits
);
19
entriesByHash
= (
Heap
::
StringOrSymbol
**)
malloc
(
alloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
20
entriesById
= (
Heap
::
StringOrSymbol
**)
malloc
(
alloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
21
memset
(
entriesByHash
, 0,
alloc
*
sizeof
(
Heap
::
String
*));
22
memset
(
entriesById
, 0,
alloc
*
sizeof
(
Heap
::
String
*));
23
}
24
25
IdentifierTable
::~
IdentifierTable
()
26
{
27
free
(
entriesByHash
);
28
free
(
entriesById
);
29
for
(
const
auto
&
h
:
std
::
as_const
(
idHashes
))
30
h
->
identifierTable
=
nullptr
;
31
}
32
33
void
IdentifierTable
::
addEntry
(
Heap
::
StringOrSymbol
*
str
)
34
{
35
uint
hash
=
str
->
hashValue
();
36
37
if
(
str
->
subtype
==
Heap
::
String
::
StringType_ArrayIndex
)
38
return
;
39
40
str
->
identifier
=
PropertyKey
::
fromStringOrSymbol
(
engine
,
str
);
41
42
bool
grow
= (
alloc
<=
size
*2);
43
44
if
(
grow
) {
45
++
numBits
;
46
int
newAlloc
=
qPrimeForNumBits
(
numBits
);
47
Heap
::
StringOrSymbol
**
newEntries
= (
Heap
::
StringOrSymbol
**)
malloc
(
newAlloc
*
sizeof
(
Heap
::
String
*));
48
memset
(
newEntries
, 0,
newAlloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
49
for
(
uint
i
= 0;
i
<
alloc
; ++
i
) {
50
Heap
::
StringOrSymbol
*
e
=
entriesByHash
[
i
];
51
if
(!
e
)
52
continue
;
53
uint
idx
=
e
->
stringHash
%
newAlloc
;
54
while
(
newEntries
[
idx
]) {
55
++
idx
;
56
idx
%=
newAlloc
;
57
}
58
newEntries
[
idx
] =
e
;
59
}
60
free
(
entriesByHash
);
61
entriesByHash
=
newEntries
;
62
63
newEntries
= (
Heap
::
StringOrSymbol
**)
malloc
(
newAlloc
*
sizeof
(
Heap
::
String
*));
64
memset
(
newEntries
, 0,
newAlloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
65
for
(
uint
i
= 0;
i
<
alloc
; ++
i
) {
66
Heap
::
StringOrSymbol
*
e
=
entriesById
[
i
];
67
if
(!
e
)
68
continue
;
69
uint
idx
=
e
->
identifier
.
id
() %
newAlloc
;
70
while
(
newEntries
[
idx
]) {
71
++
idx
;
72
idx
%=
newAlloc
;
73
}
74
newEntries
[
idx
] =
e
;
75
}
76
free
(
entriesById
);
77
entriesById
=
newEntries
;
78
79
alloc
=
newAlloc
;
80
}
81
82
uint
idx
=
hash
%
alloc
;
83
while
(
entriesByHash
[
idx
]) {
84
++
idx
;
85
idx
%=
alloc
;
86
}
87
entriesByHash
[
idx
] =
str
;
88
89
idx
=
str
->
identifier
.
id
() %
alloc
;
90
while
(
entriesById
[
idx
]) {
91
++
idx
;
92
idx
%=
alloc
;
93
}
94
entriesById
[
idx
] =
str
;
95
96
++
size
;
97
}
98
99
100
101
Heap
::
String
*
IdentifierTable
::
insertString
(
const
QString
&
s
)
102
{
103
uint
subtype
;
104
uint
hash
=
String
::
createHashValue
(
s
.
constData
(),
s
.
size
(), &
subtype
);
105
if
(
subtype
==
Heap
::
String
::
StringType_ArrayIndex
) {
106
Heap
::
String
*
str
=
engine
->
newString
(
s
);
107
str
->
stringHash
=
hash
;
108
str
->
subtype
=
subtype
;
109
str
->
identifier
=
PropertyKey
::
fromArrayIndex
(
hash
);
110
return
str
;
111
}
112
return
resolveStringEntry
(
s
,
hash
,
subtype
);
113
}
114
115
Heap
::
String
*
IdentifierTable
::
resolveStringEntry
(
const
QString
&
s
,
uint
hash
,
uint
subtype
)
116
{
117
uint
idx
=
hash
%
alloc
;
118
while
(
Heap
::
StringOrSymbol
*
e
=
entriesByHash
[
idx
]) {
119
if
(
e
->
stringHash
==
hash
&&
e
->
toQString
() ==
s
)
120
return
static_cast
<
Heap
::
String
*>(
e
);
121
++
idx
;
122
idx
%=
alloc
;
123
}
124
125
Heap
::
String
*
str
=
engine
->
newString
(
s
);
126
str
->
stringHash
=
hash
;
127
str
->
subtype
=
subtype
;
128
addEntry
(
str
);
129
return
str
;
130
}
131
132
Heap
::
Symbol
*
IdentifierTable
::
insertSymbol
(
const
QString
&
s
)
133
{
134
Q_ASSERT
(
s
.
at
(0) ==
QLatin1Char
(
'@'
));
135
136
uint
subtype
;
137
uint
hash
=
String
::
createHashValue
(
s
.
constData
(),
s
.
size
(), &
subtype
);
138
uint
idx
=
hash
%
alloc
;
139
while
(
Heap
::
StringOrSymbol
*
e
=
entriesByHash
[
idx
]) {
140
if
(
e
->
stringHash
==
hash
&&
e
->
toQString
() ==
s
)
141
return
static_cast
<
Heap
::
Symbol
*>(
e
);
142
++
idx
;
143
idx
%=
alloc
;
144
}
145
146
Heap
::
Symbol
*
str
=
Symbol
::
create
(
engine
,
s
);
147
str
->
stringHash
=
hash
;
148
str
->
subtype
=
subtype
;
149
addEntry
(
str
);
150
return
str
;
151
152
}
153
154
155
PropertyKey
IdentifierTable
::
asPropertyKeyImpl
(
const
Heap
::
String
*
str
)
156
{
157
if
(
str
->
identifier
.
isValid
())
158
return
str
->
identifier
;
159
uint
hash
=
str
->
hashValue
();
160
if
(
str
->
subtype
==
Heap
::
String
::
StringType_ArrayIndex
) {
161
str
->
identifier
=
PropertyKey
::
fromArrayIndex
(
hash
);
162
return
str
->
identifier
;
163
}
164
165
uint
idx
=
hash
%
alloc
;
166
while
(
Heap
::
StringOrSymbol
*
e
=
entriesByHash
[
idx
]) {
167
if
(
e
->
stringHash
==
hash
&&
e
->
toQString
() ==
str
->
toQString
()) {
168
str
->
identifier
=
e
->
identifier
;
169
QV4
::
WriteBarrier
::
markCustom
(
engine
, [&](
QV4
::
MarkStack
*
stack
) {
170
e
->
identifier
.
asStringOrSymbol
()->
mark
(
stack
);
171
});
172
return
e
->
identifier
;
173
}
174
++
idx
;
175
idx
%=
alloc
;
176
}
177
178
addEntry
(
const_cast
<
QV4
::
Heap
::
String
*>(
str
));
179
return
str
->
identifier
;
180
}
181
182
Heap
::
StringOrSymbol
*
IdentifierTable
::
resolveId
(
PropertyKey
i
)
const
183
{
184
if
(
i
.
isArrayIndex
())
185
return
engine
->
newString
(
QString
::
number
(
i
.
asArrayIndex
()));
186
if
(!
i
.
isValid
())
187
return
nullptr
;
188
189
uint
idx
=
i
.
id
() %
alloc
;
190
while
(1) {
191
Heap
::
StringOrSymbol
*
e
=
entriesById
[
idx
];
192
if
(!
e
||
e
->
identifier
==
i
)
193
return
e
;
194
++
idx
;
195
idx
%=
alloc
;
196
}
197
}
198
199
Heap
::
String
*
IdentifierTable
::
stringForId
(
PropertyKey
i
)
const
200
{
201
Heap
::
StringOrSymbol
*
s
=
resolveId
(
i
);
202
Q_ASSERT
(
s
&&
s
->
internalClass
->
vtable
->
isString
);
203
return
static_cast
<
Heap
::
String
*>(
s
);
204
}
205
206
Heap
::
Symbol
*
IdentifierTable
::
symbolForId
(
PropertyKey
i
)
const
207
{
208
Heap
::
StringOrSymbol
*
s
=
resolveId
(
i
);
209
Q_ASSERT
(!
s
|| !
s
->
internalClass
->
vtable
->
isString
);
210
return
static_cast
<
Heap
::
Symbol
*>(
s
);
211
}
212
213
void
IdentifierTable
::
markObjects
(
MarkStack
*
markStack
)
214
{
215
for
(
const
auto
&
h
:
idHashes
)
216
h
->
markObjects
(
markStack
);
217
}
218
219
void
IdentifierTable
::
sweep
()
220
{
221
int
freed
= 0;
222
223
Heap
::
StringOrSymbol
**
newTable
= (
Heap
::
StringOrSymbol
**)
malloc
(
alloc
*
sizeof
(
Heap
::
String
*));
224
memset
(
newTable
, 0,
alloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
225
memset
(
entriesById
, 0,
alloc
*
sizeof
(
Heap
::
StringOrSymbol
*));
226
for
(
uint
i
= 0;
i
<
alloc
; ++
i
) {
227
Heap
::
StringOrSymbol
*
e
=
entriesByHash
[
i
];
228
if
(!
e
)
229
continue
;
230
if
(!
e
->
isMarked
()) {
231
++
freed
;
232
continue
;
233
}
234
uint
idx
=
e
->
hashValue
() %
alloc
;
235
while
(
newTable
[
idx
]) {
236
++
idx
;
237
if
(
idx
==
alloc
)
238
idx
= 0;
239
}
240
newTable
[
idx
] =
e
;
241
242
idx
=
e
->
identifier
.
id
() %
alloc
;
243
while
(
entriesById
[
idx
]) {
244
++
idx
;
245
if
(
idx
==
alloc
)
246
idx
= 0;
247
}
248
entriesById
[
idx
] =
e
;
249
}
250
free
(
entriesByHash
);
251
entriesByHash
=
newTable
;
252
253
size
-=
freed
;
254
}
255
256
PropertyKey
IdentifierTable
::
asPropertyKey
(
const
QString
&
s
,
257
IdentifierTable
::
KeyConversionBehavior
conversionBehvior
)
258
{
259
uint
subtype
;
260
uint
hash
=
String
::
createHashValue
(
s
.
constData
(),
s
.
size
(), &
subtype
);
261
if
(
subtype
==
Heap
::
String
::
StringType_ArrayIndex
) {
262
if
(
Q_UNLIKELY
(
conversionBehvior
==
ForceConversionToId
))
263
hash
=
String
::
createHashValueDisallowingArrayIndex
(
s
.
constData
(),
s
.
size
(), &
subtype
);
264
else
265
return
PropertyKey
::
fromArrayIndex
(
hash
);
266
}
267
return
resolveStringEntry
(
s
,
hash
,
subtype
)->
identifier
;
268
}
269
270
}
271
272
QT_END_NAMESPACE
QPlatformGraphicsBufferHelper
\inmodule QtGui
QV4
Definition
qjsvalue.h:23
qtdeclarative
src
qml
jsruntime
qv4identifiertable.cpp
Generated on
for Qt by
1.14.0