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
qv4executablecompilationunit.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 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
4
#
include
"qml/qqmlprivate.h"
5
#
include
"qv4engine_p.h"
6
#
include
"qv4executablecompilationunit_p.h"
7
8
#
include
<
private
/
qv4engine_p
.
h
>
9
#
include
<
private
/
qv4regexp_p
.
h
>
10
#
include
<
private
/
qv4lookup_p
.
h
>
11
#
include
<
private
/
qv4qmlcontext_p
.
h
>
12
#
include
<
private
/
qv4identifiertable_p
.
h
>
13
#
include
<
private
/
qv4objectproto_p
.
h
>
14
#
include
<
private
/
qqmlengine_p
.
h
>
15
#
include
<
private
/
qv4qobjectwrapper_p
.
h
>
16
#
include
<
private
/
qqmlvaluetypewrapper_p
.
h
>
17
#
include
<
private
/
qqmlscriptdata_p
.
h
>
18
#
include
<
private
/
qv4module_p
.
h
>
19
#
include
<
private
/
qv4compilationunitmapper_p
.
h
>
20
#
include
<
private
/
qqmltypewrapper_p
.
h
>
21
#
include
<
private
/
qv4resolvedtypereference_p
.
h
>
22
#
include
<
private
/
qv4objectiterator_p
.
h
>
23
24
#
include
<
QtQml
/
qqmlpropertymap
.
h
>
25
26
#
include
<
QtCore
/
qfileinfo
.
h
>
27
#
include
<
QtCore
/
qcryptographichash
.
h
>
28
29
QT_BEGIN_NAMESPACE
30
31
namespace
QV4
{
32
33
ExecutableCompilationUnit
::
ExecutableCompilationUnit
() =
default
;
34
35
ExecutableCompilationUnit
::
ExecutableCompilationUnit
(
36
QQmlRefPointer
<
CompiledData
::
CompilationUnit
> &&
compilationUnit
)
37
:
m_compilationUnit
(
std
::
move
(
compilationUnit
))
38
{
39
constants
=
m_compilationUnit
->
constants
;
40
}
41
42
ExecutableCompilationUnit
::~
ExecutableCompilationUnit
()
43
{
44
if
(
engine
)
45
clear
();
46
}
47
48
static
QString
toString
(QV4::ReturnedValue v)
49
{
50
Value val = Value::fromReturnedValue(v);
51
QString result;
52
if
(val.isInt32())
53
result = QLatin1String(
"int "
);
54
else
if
(val.isDouble())
55
result = QLatin1String(
"double "
);
56
if
(val.isEmpty())
57
result += QLatin1String(
"empty"
);
58
else
59
result += val.toQStringNoThrow();
60
return
result;
61
}
62
63
static
void
dumpConstantTable
(
const
StaticValue *constants, uint count)
64
{
65
QDebug d = qDebug();
66
d.nospace() << Qt::right;
67
for
(uint i = 0; i < count; ++i) {
68
d << qSetFieldWidth(8) << i << qSetFieldWidth(0) <<
": "
69
<< toString(constants[i].asReturnedValue()).toUtf8().constData() <<
"\n"
;
70
}
71
}
72
73
void
ExecutableCompilationUnit
::
populate
()
74
{
75
/* In general, we should use QV4::Scope whenever we allocate heap objects, and employ write barriers
76
for member variables pointing to heap objects. However, ExecutableCompilationUnit is special, as it
77
is always part of the root set. So instead of using scoped allocations and write barriers, we use a
78
slightly different approach: We temporarily block the gc from running. Afterwards, at the end of the
79
function we check whether the gc was already running, and mark the ExecutableCompilationUnit. This
80
ensures that all the newly allocated objects of the compilation unit will be marked in turn.
81
If the gc was not running, we don't have to do anything, because everything will be marked when the
82
gc starts marking the root set at the start of a run.
83
*/
84
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
85
GCCriticalSection
<
ExecutableCompilationUnit
>
criticalSection
(
engine
,
this
);
86
87
Q_ASSERT
(!
runtimeStrings
);
88
Q_ASSERT
(
engine
);
89
Q_ASSERT
(
data
);
90
const
quint32
stringCount
=
totalStringCount
();
91
runtimeStrings
= (
QV4
::
Heap
::
String
**)
calloc
(
stringCount
,
sizeof
(
QV4
::
Heap
::
String
*));
92
for
(
uint
i
= 0;
i
<
stringCount
; ++
i
)
93
runtimeStrings
[
i
] =
engine
->
newString
(
stringAt
(
i
));
94
95
runtimeRegularExpressions
96
=
new
QV4
::
Value
[
data
->
regexpTableSize
];
97
for
(
uint
i
= 0;
i
<
data
->
regexpTableSize
; ++
i
) {
98
const
CompiledData
::
RegExp
*
re
=
data
->
regexpAt
(
i
);
99
uint
f
=
re
->
flags
();
100
const
CompiledData
::
RegExp
::
Flags
flags
=
static_cast
<
CompiledData
::
RegExp
::
Flags
>(
f
);
101
runtimeRegularExpressions
[
i
] =
QV4
::
RegExp
::
create
(
102
engine
,
stringAt
(
re
->
stringIndex
()),
flags
);
103
}
104
105
if
(
data
->
lookupTableSize
) {
106
runtimeLookups
=
new
QV4
::
Lookup
[
data
->
lookupTableSize
];
107
memset
(
runtimeLookups
, 0,
data
->
lookupTableSize
*
sizeof
(
QV4
::
Lookup
));
108
const
CompiledData
::
Lookup
*
compiledLookups
=
data
->
lookupTable
();
109
for
(
uint
i
= 0;
i
<
data
->
lookupTableSize
; ++
i
) {
110
QV4
::
Lookup
*
l
=
runtimeLookups
+
i
;
111
112
CompiledData
::
Lookup
::
Type
type
113
=
CompiledData
::
Lookup
::
Type
(
uint
(
compiledLookups
[
i
].
type
()));
114
if
(
type
==
CompiledData
::
Lookup
::
Type_Getter
)
115
l
->
call
=
Lookup
::
Call
::
GetterGeneric
;
116
else
if
(
type
==
CompiledData
::
Lookup
::
Type_Setter
)
117
l
->
call
=
Lookup
::
Call
::
SetterGeneric
;
118
else
if
(
type
==
CompiledData
::
Lookup
::
Type_GlobalGetter
)
119
l
->
call
=
Lookup
::
Call
::
GlobalGetterGeneric
;
120
else
if
(
type
==
CompiledData
::
Lookup
::
Type_QmlContextPropertyGetter
)
121
l
->
call
=
Lookup
::
Call
::
ContextGetterGeneric
;
122
l
->
forCall
=
compiledLookups
[
i
].
mode
() ==
CompiledData
::
Lookup
::
Mode_ForCall
;
123
l
->
nameIndex
=
compiledLookups
[
i
].
nameIndex
();
124
}
125
}
126
127
if
(
data
->
jsClassTableSize
) {
128
runtimeClasses
129
= (
QV4
::
Heap
::
InternalClass
**)
calloc
(
data
->
jsClassTableSize
,
130
sizeof
(
QV4
::
Heap
::
InternalClass
*));
131
132
for
(
uint
i
= 0;
i
<
data
->
jsClassTableSize
; ++
i
) {
133
int
memberCount
= 0;
134
const
CompiledData
::
JSClassMember
*
member
135
=
data
->
jsClassAt
(
i
, &
memberCount
);
136
runtimeClasses
[
i
]
137
=
engine
->
internalClasses
(
QV4
::
ExecutionEngine
::
Class_Object
);
138
for
(
int
j
= 0;
j
<
memberCount
; ++
j
, ++
member
)
139
runtimeClasses
[
i
]
140
=
runtimeClasses
[
i
]->
addMember
(
141
engine
->
identifierTable
->
asPropertyKey
(
142
runtimeStrings
[
member
->
nameOffset
()]),
143
member
->
isAccessor
()
144
?
QV4
::
Attr_Accessor
145
:
QV4
::
Attr_Data
);
146
}
147
}
148
149
runtimeFunctions
.
resize
(
data
->
functionTableSize
);
150
static
bool
ignoreAotCompiledFunctions
151
=
qEnvironmentVariableIsSet
(
"QV4_FORCE_INTERPRETER"
)
152
|| !(
engine
->
diskCacheOptions
() &
ExecutionEngine
::
DiskCache
::
AotNative
);
153
154
const
QQmlPrivate
::
AOTCompiledFunction
*
aotFunction
155
=
ignoreAotCompiledFunctions
?
nullptr
:
m_compilationUnit
->
aotCompiledFunctions
;
156
157
auto
advanceAotFunction
= [&](
int
i
) ->
const
QQmlPrivate
::
AOTCompiledFunction
* {
158
if
(
aotFunction
) {
159
if
(
aotFunction
->
functionPtr
) {
160
if
(
aotFunction
->
functionIndex
==
i
)
161
return
aotFunction
++;
162
}
else
{
163
aotFunction
=
nullptr
;
164
}
165
}
166
return
nullptr
;
167
};
168
169
for
(
int
i
= 0 ;
i
<
runtimeFunctions
.
size
(); ++
i
) {
170
const
QV4
::
CompiledData
::
Function
*
compiledFunction
=
data
->
functionAt
(
i
);
171
runtimeFunctions
[
i
] =
QV4
::
Function
::
create
(
engine
,
this
,
compiledFunction
,
172
advanceAotFunction
(
i
));
173
}
174
175
Scope
scope
(
engine
);
176
Scoped
<
InternalClass
>
ic
(
scope
);
177
178
runtimeBlocks
.
resize
(
data
->
blockTableSize
);
179
for
(
int
i
= 0 ;
i
<
runtimeBlocks
.
size
(); ++
i
) {
180
const
QV4
::
CompiledData
::
Block
*
compiledBlock
=
data
->
blockAt
(
i
);
181
ic
=
engine
->
internalClasses
(
EngineBase
::
Class_CallContext
);
182
183
// first locals
184
const
quint32_le
*
localsIndices
=
compiledBlock
->
localsTable
();
185
for
(
quint32
j
= 0;
j
<
compiledBlock
->
nLocals
; ++
j
)
186
ic
=
ic
->
addMember
(
187
engine
->
identifierTable
->
asPropertyKey
(
runtimeStrings
[
localsIndices
[
j
]]),
188
Attr_NotConfigurable
);
189
runtimeBlocks
[
i
] =
ic
->
d
();
190
}
191
192
static
const
bool
showCode
=
qEnvironmentVariableIsSet
(
"QV4_SHOW_BYTECODE"
);
193
if
(
showCode
) {
194
qDebug
() <<
"=== Constant table"
;
195
dumpConstantTable
(
constants
,
data
->
constantTableSize
);
196
qDebug
() <<
"=== String table"
;
197
for
(
uint
i
= 0,
end
=
totalStringCount
();
i
<
end
; ++
i
)
198
qDebug
() <<
" "
<<
i
<<
":"
<<
runtimeStrings
[
i
]->
toQString
();
199
qDebug
() <<
"=== Closure table"
;
200
for
(
uint
i
= 0;
i
<
data
->
functionTableSize
; ++
i
)
201
qDebug
() <<
" "
<<
i
<<
":"
<<
runtimeFunctions
[
i
]->
name
()->
toQString
();
202
qDebug
() <<
"root function at index "
203
<< (
data
->
indexOfRootFunction
!= -1
204
?
data
->
indexOfRootFunction
: 0);
205
}
206
}
207
208
Heap
::
Object
*
ExecutableCompilationUnit
::
templateObjectAt
(
int
index
)
const
209
{
210
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
211
Q_ASSERT
(
data
);
212
Q_ASSERT
(
engine
);
213
214
Q_ASSERT
(
index
<
int
(
data
->
templateObjectTableSize
));
215
if
(!
templateObjects
.
size
())
216
templateObjects
.
resize
(
data
->
templateObjectTableSize
);
217
Heap
::
Object
*
o
=
templateObjects
.
at
(
index
);
218
if
(
o
)
219
return
o
;
220
221
// create the template object
222
Scope
scope
(
engine
);
223
const
CompiledData
::
TemplateObject
*
t
=
data
->
templateObjectAt
(
index
);
224
Scoped
<
ArrayObject
>
a
(
scope
,
engine
->
newArrayObject
(
t
->
size
));
225
Scoped
<
ArrayObject
>
raw
(
scope
,
engine
->
newArrayObject
(
t
->
size
));
226
ScopedValue
s
(
scope
);
227
for
(
uint
i
= 0;
i
<
t
->
size
; ++
i
) {
228
s
=
runtimeStrings
[
t
->
stringIndexAt
(
i
)];
229
a
->
arraySet
(
i
,
s
);
230
s
=
runtimeStrings
[
t
->
rawStringIndexAt
(
i
)];
231
raw
->
arraySet
(
i
,
s
);
232
}
233
234
ObjectPrototype
::
method_freeze
(
engine
->
functionCtor
(),
nullptr
,
raw
, 1);
235
a
->
defineReadonlyProperty
(
QStringLiteral
(
"raw"
),
raw
);
236
ObjectPrototype
::
method_freeze
(
engine
->
functionCtor
(),
nullptr
,
a
, 1);
237
238
templateObjects
[
index
] =
a
->
objectValue
()->
d
();
239
return
templateObjects
.
at
(
index
);
240
}
241
242
void
ExecutableCompilationUnit
::
clear
()
243
{
244
delete
[]
imports
;
245
imports
=
nullptr
;
246
247
if
(
runtimeLookups
) {
248
const
uint
lookupTableSize
=
unitData
()->
lookupTableSize
;
249
for
(
uint
i
= 0;
i
<
lookupTableSize
; ++
i
)
250
runtimeLookups
[
i
].
releasePropertyCache
();
251
}
252
253
delete
[]
runtimeLookups
;
254
runtimeLookups
=
nullptr
;
255
256
for
(
QV4
::
Function
*
f
:
std
::
as_const
(
runtimeFunctions
))
257
f
->
destroy
();
258
runtimeFunctions
.
clear
();
259
260
free
(
runtimeStrings
);
261
runtimeStrings
=
nullptr
;
262
delete
[]
runtimeRegularExpressions
;
263
runtimeRegularExpressions
=
nullptr
;
264
free
(
runtimeClasses
);
265
runtimeClasses
=
nullptr
;
266
267
static
QQmlRefPointer
<
CompiledData
::
CompilationUnit
>
nullUnit
268
=
QQml
::
makeRefPointer
<
CompiledData
::
CompilationUnit
>();
269
m_compilationUnit
=
nullUnit
;
270
}
271
272
void
ExecutableCompilationUnit
::
markObjects
(
QV4
::
MarkStack
*
markStack
)
const
273
{
274
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
275
276
if
(
runtimeStrings
) {
277
for
(
uint
i
= 0,
end
=
totalStringCount
();
i
<
end
; ++
i
)
278
if
(
runtimeStrings
[
i
])
279
runtimeStrings
[
i
]->
mark
(
markStack
);
280
}
281
if
(
runtimeRegularExpressions
) {
282
for
(
uint
i
= 0;
i
<
data
->
regexpTableSize
; ++
i
)
283
Value
::
fromStaticValue
(
runtimeRegularExpressions
[
i
]).
mark
(
markStack
);
284
}
285
if
(
runtimeClasses
) {
286
for
(
uint
i
= 0;
i
<
data
->
jsClassTableSize
; ++
i
)
287
if
(
runtimeClasses
[
i
])
288
runtimeClasses
[
i
]->
mark
(
markStack
);
289
}
290
for
(
QV4
::
Function
*
f
:
std
::
as_const
(
runtimeFunctions
))
291
if
(
f
&&
f
->
internalClass
)
292
f
->
internalClass
->
mark
(
markStack
);
293
for
(
QV4
::
Heap
::
InternalClass
*
c
:
std
::
as_const
(
runtimeBlocks
))
294
if
(
c
)
295
c
->
mark
(
markStack
);
296
297
for
(
QV4
::
Heap
::
Object
*
o
:
std
::
as_const
(
templateObjects
))
298
if
(
o
)
299
o
->
mark
(
markStack
);
300
301
if
(
runtimeLookups
) {
302
for
(
uint
i
= 0;
i
<
data
->
lookupTableSize
; ++
i
)
303
runtimeLookups
[
i
].
markObjects
(
markStack
);
304
}
305
306
if
(
Heap
::
Base
*
v
=
m_valueOrModule
.
heapObject
())
307
v
->
mark
(
markStack
);
308
}
309
310
IdentifierHash
ExecutableCompilationUnit
::
createNamedObjectsPerComponent
(
int
componentObjectIndex
)
311
{
312
IdentifierHash
namedObjectCache
(
engine
);
313
const
CompiledData
::
Object
*
component
=
objectAt
(
componentObjectIndex
);
314
const
quint32_le
*
namedObjectIndexPtr
=
component
->
namedObjectsInComponentTable
();
315
for
(
quint32
i
= 0;
i
<
component
->
nNamedObjectsInComponent
; ++
i
, ++
namedObjectIndexPtr
) {
316
const
CompiledData
::
Object
*
namedObject
=
objectAt
(*
namedObjectIndexPtr
);
317
namedObjectCache
.
add
(
runtimeStrings
[
namedObject
->
idNameIndex
],
namedObject
->
objectId
());
318
}
319
Q_ASSERT
(!
namedObjectCache
.
isEmpty
());
320
return
*
namedObjectsPerComponentCache
.
insert
(
componentObjectIndex
,
namedObjectCache
);
321
}
322
323
QQmlRefPointer
<
ExecutableCompilationUnit
>
ExecutableCompilationUnit
::
create
(
324
QQmlRefPointer
<
CompiledData
::
CompilationUnit
> &&
compilationUnit
,
ExecutionEngine
*
engine
)
325
{
326
auto
result
=
QQmlRefPointer
<
ExecutableCompilationUnit
>(
327
new
ExecutableCompilationUnit
(
std
::
move
(
compilationUnit
)),
328
QQmlRefPointer
<
ExecutableCompilationUnit
>::
Adopt
);
329
result
->
engine
=
engine
;
330
return
result
;
331
}
332
333
Heap
::
Module
*
ExecutableCompilationUnit
::
instantiate
()
334
{
335
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
336
337
if
(
isESModule
() &&
module
())
338
return
module
();
339
340
if
(
data
->
indexOfRootFunction
< 0)
341
return
nullptr
;
342
343
Q_ASSERT
(
engine
);
344
if
(!
runtimeStrings
)
345
populate
();
346
347
Scope
scope
(
engine
);
348
Scoped
<
Module
>
module
(
scope
,
engine
->
memoryManager
->
allocate
<
Module
>(
engine
,
this
));
349
350
if
(
isESModule
())
351
setModule
(
module
->
d
());
352
353
const
QStringList
moduleRequests
=
m_compilationUnit
->
moduleRequests
();
354
for
(
const
QString
&
request
:
moduleRequests
) {
355
const
QUrl
url
(
request
);
356
const
auto
dependentModuleUnit
=
engine
->
loadModule
(
url
,
this
);
357
if
(
engine
->
hasException
)
358
return
nullptr
;
359
if
(
dependentModuleUnit
)
360
dependentModuleUnit
->
instantiate
();
361
}
362
363
ScopedString
importName
(
scope
);
364
365
const
uint
importCount
=
data
->
importEntryTableSize
;
366
if
(
importCount
> 0) {
367
imports
=
new
const
StaticValue
*[
importCount
];
368
memset
(
imports
, 0,
importCount
*
sizeof
(
StaticValue
*));
369
}
370
for
(
uint
i
= 0;
i
<
importCount
; ++
i
) {
371
const
CompiledData
::
ImportEntry
&
entry
=
data
->
importEntryTable
()[
i
];
372
QUrl
url
=
urlAt
(
entry
.
moduleRequest
);
373
importName
=
runtimeStrings
[
entry
.
importName
];
374
375
if
(
const
auto
module
=
engine
->
loadModule
(
url
,
this
)) {
376
const
Value
*
valuePtr
=
module
->
resolveExport
(
importName
);
377
if
(!
valuePtr
) {
378
QString
referenceErrorMessage
=
QStringLiteral
(
"Unable to resolve import reference "
);
379
referenceErrorMessage
+=
importName
->
toQString
();
380
QV4
::
ScopedValue
compiledValue
(
scope
,
module
->
value
());
381
engine
->
throwReferenceError
(
382
referenceErrorMessage
,
fileName
(),
383
entry
.
location
.
line
(),
entry
.
location
.
column
());
384
return
nullptr
;
385
}
386
imports
[
i
] =
valuePtr
;
387
}
388
}
389
390
const
auto
throwReferenceError
= [&](
const
CompiledData
::
ExportEntry
&
entry
,
const
QString
&
importName
) {
391
QString
referenceErrorMessage
=
QStringLiteral
(
"Unable to resolve re-export reference "
);
392
referenceErrorMessage
+=
importName
;
393
engine
->
throwReferenceError
(
394
referenceErrorMessage
,
fileName
(),
395
entry
.
location
.
line
(),
entry
.
location
.
column
());
396
};
397
398
for
(
uint
i
= 0;
i
<
data
->
indirectExportEntryTableSize
; ++
i
) {
399
const
CompiledData
::
ExportEntry
&
entry
=
data
->
indirectExportEntryTable
()[
i
];
400
if
(
auto
dependentModule
=
engine
->
loadModule
(
urlAt
(
entry
.
moduleRequest
),
this
)) {
401
ScopedString
importName
(
scope
,
runtimeStrings
[
entry
.
importName
]);
402
if
(!
dependentModule
->
resolveExport
(
importName
)) {
403
throwReferenceError
(
entry
,
importName
->
toQString
());
404
return
nullptr
;
405
}
406
}
407
}
408
409
return
module
->
d
();
410
}
411
412
const
Value
*
ExecutableCompilationUnit
::
resolveExportRecursively
(
413
QV4
::
String
*
exportName
,
QVector
<
ResolveSetEntry
> *
resolveSet
)
414
{
415
if
(!
module
())
416
return
nullptr
;
417
418
for
(
const
auto
&
entry
: *
resolveSet
)
419
if
(
entry
.
module
==
this
&&
entry
.
exportName
->
isEqualTo
(
exportName
))
420
return
nullptr
;
421
422
(*
resolveSet
) <<
ResolveSetEntry
(
this
,
exportName
);
423
424
if
(
exportName
->
toQString
() ==
QLatin1String
(
"*"
))
425
return
&
module
()->
self
;
426
427
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
428
429
Q_ASSERT
(
data
);
430
Q_ASSERT
(
engine
);
431
432
Scope
scope
(
engine
);
433
434
if
(
auto
localExport
=
lookupNameInExportTable
(
435
data
->
localExportEntryTable
(),
data
->
localExportEntryTableSize
,
exportName
)) {
436
ScopedString
localName
(
scope
,
runtimeStrings
[
localExport
->
localName
]);
437
uint
index
=
module
()->
scope
->
internalClass
->
indexOfValueOrGetter
(
localName
->
toPropertyKey
());
438
if
(
index
==
UINT_MAX
)
439
return
nullptr
;
440
if
(
index
>=
module
()->
scope
->
locals
.
size
)
441
return
&(
imports
[
index
-
module
()->
scope
->
locals
.
size
]->
asValue
<
Value
>());
442
return
&
module
()->
scope
->
locals
[
index
];
443
}
444
445
if
(
auto
indirectExport
=
lookupNameInExportTable
(
446
data
->
indirectExportEntryTable
(),
data
->
indirectExportEntryTableSize
,
exportName
)) {
447
QUrl
request
=
urlAt
(
indirectExport
->
moduleRequest
);
448
if
(
auto
dependentModule
=
engine
->
loadModule
(
request
,
this
)) {
449
ScopedString
importName
(
scope
,
runtimeStrings
[
indirectExport
->
importName
]);
450
return
dependentModule
->
resolveExportRecursively
(
importName
,
resolveSet
);
451
}
452
return
nullptr
;
453
}
454
455
if
(
exportName
->
toQString
() ==
QLatin1String
(
"default"
))
456
return
nullptr
;
457
458
const
Value
*
starResolution
=
nullptr
;
459
460
for
(
uint
i
= 0;
i
<
data
->
starExportEntryTableSize
; ++
i
) {
461
const
CompiledData
::
ExportEntry
&
entry
=
data
->
starExportEntryTable
()[
i
];
462
QUrl
request
=
urlAt
(
entry
.
moduleRequest
);
463
const
Value
*
resolution
=
nullptr
;
464
if
(
auto
dependentModule
=
engine
->
loadModule
(
request
,
this
))
465
resolution
=
dependentModule
->
resolveExportRecursively
(
exportName
,
resolveSet
);
466
467
// ### handle ambiguous
468
if
(
resolution
) {
469
if
(!
starResolution
) {
470
starResolution
=
resolution
;
471
continue
;
472
}
473
if
(
resolution
!=
starResolution
)
474
return
nullptr
;
475
}
476
}
477
478
return
starResolution
;
479
}
480
481
const
CompiledData
::
ExportEntry
*
ExecutableCompilationUnit
::
lookupNameInExportTable
(
482
const
CompiledData
::
ExportEntry
*
firstExportEntry
,
int
tableSize
,
QV4
::
String
*
name
)
const
483
{
484
const
CompiledData
::
ExportEntry
*
lastExportEntry
=
firstExportEntry
+
tableSize
;
485
auto
matchingExport
=
std
::
lower_bound
(
firstExportEntry
,
lastExportEntry
,
name
, [
this
](
const
CompiledData
::
ExportEntry
&
lhs
,
QV4
::
String
*
name
) {
486
return
stringAt
(
lhs
.
exportName
) <
name
->
toQString
();
487
});
488
if
(
matchingExport
==
lastExportEntry
||
stringAt
(
matchingExport
->
exportName
) !=
name
->
toQString
())
489
return
nullptr
;
490
return
matchingExport
;
491
}
492
493
void
ExecutableCompilationUnit
::
getExportedNamesRecursively
(
494
QStringList
*
names
,
QVector
<
const
ExecutableCompilationUnit
*> *
exportNameSet
,
495
bool
includeDefaultExport
)
const
496
{
497
if
(
exportNameSet
->
contains
(
this
))
498
return
;
499
exportNameSet
->
append
(
this
);
500
501
const
auto
append
= [
names
,
includeDefaultExport
](
const
QString
&
name
) {
502
if
(!
includeDefaultExport
&&
name
==
QLatin1String
(
"default"
))
503
return
;
504
names
->
append
(
name
);
505
};
506
507
const
CompiledData
::
Unit
*
data
=
m_compilationUnit
->
data
;
508
509
Q_ASSERT
(
data
);
510
Q_ASSERT
(
engine
);
511
512
for
(
uint
i
= 0;
i
<
data
->
localExportEntryTableSize
; ++
i
) {
513
const
CompiledData
::
ExportEntry
&
entry
=
data
->
localExportEntryTable
()[
i
];
514
append
(
stringAt
(
entry
.
exportName
));
515
}
516
517
for
(
uint
i
= 0;
i
<
data
->
indirectExportEntryTableSize
; ++
i
) {
518
const
CompiledData
::
ExportEntry
&
entry
=
data
->
indirectExportEntryTable
()[
i
];
519
append
(
stringAt
(
entry
.
exportName
));
520
}
521
522
for
(
uint
i
= 0;
i
<
data
->
starExportEntryTableSize
; ++
i
) {
523
const
CompiledData
::
ExportEntry
&
entry
=
data
->
starExportEntryTable
()[
i
];
524
if
(
auto
dependentModule
=
engine
->
loadModule
(
urlAt
(
entry
.
moduleRequest
),
this
)) {
525
dependentModule
->
getExportedNamesRecursively
(
526
names
,
exportNameSet
,
/*includeDefaultExport*/
false
);
527
}
528
}
529
}
530
531
void
ExecutableCompilationUnit
::
evaluate
()
532
{
533
Q_ASSERT
(
engine
);
534
535
QV4
::
Scope
scope
(
engine
);
536
QV4
::
Scoped
<
Module
>
mod
(
scope
,
module
());
537
mod
->
evaluate
();
538
}
539
540
void
ExecutableCompilationUnit
::
evaluateModuleRequests
()
541
{
542
Q_ASSERT
(
engine
);
543
544
const
QStringList
moduleRequests
=
m_compilationUnit
->
moduleRequests
();
545
for
(
const
QString
&
request
:
moduleRequests
) {
546
auto
dependentModule
=
engine
->
loadModule
(
QUrl
(
request
),
this
);
547
548
if
(
engine
->
hasException
)
549
return
;
550
551
Q_ASSERT
(
dependentModule
);
552
dependentModule
->
evaluate
();
553
if
(
engine
->
hasException
)
554
return
;
555
}
556
}
557
558
QString
ExecutableCompilationUnit
::
bindingValueAsString
(
const
CompiledData
::
Binding
*
binding
)
const
559
{
560
#
if
QT_CONFIG
(
translation
)
561
using
namespace
CompiledData
;
562
bool
byId
=
false
;
563
switch
(
binding
->
type
()) {
564
case
Binding
::
Type_TranslationById
:
565
byId
=
true
;
566
Q_FALLTHROUGH
();
567
case
Binding
::
Type_Translation
: {
568
return
translateFrom
({
binding
->
value
.
translationDataIndex
,
byId
});
569
}
570
default
:
571
break
;
572
}
573
#
endif
574
return
m_compilationUnit
->
bindingValueAsString
(
binding
);
575
}
576
577
QString
ExecutableCompilationUnit
::
translateFrom
(
TranslationDataIndex
index
)
const
578
{
579
#
if
!
QT_CONFIG
(
translation
)
580
return
QString
();
581
#
else
582
const
CompiledData
::
TranslationData
&
translation
=
unitData
()->
translations
()[
index
.
index
];
583
584
if
(
index
.
byId
) {
585
QByteArray
id
=
stringAt
(
translation
.
stringIndex
).
toUtf8
();
586
return
qtTrId
(
id
.
constData
(),
translation
.
number
);
587
}
588
589
const
auto
fileContext
= [
this
]() {
590
// This code must match that in the qsTr() implementation
591
const
QString
&
path
=
fileName
();
592
int
lastSlash
=
path
.
lastIndexOf
(
QLatin1Char
(
'/'
));
593
594
QStringView
context
= (
lastSlash
> -1)
595
?
QStringView
{
path
}.
mid
(
lastSlash
+ 1,
path
.
size
() -
lastSlash
- 5)
596
:
QStringView
();
597
return
context
.
toUtf8
();
598
};
599
600
const
bool
hasContext
601
=
translation
.
contextIndex
!=
QV4
::
CompiledData
::
TranslationData
::
NoContextIndex
;
602
QByteArray
context
;
603
if
(
hasContext
) {
604
context
=
stringAt
(
translation
.
contextIndex
).
toUtf8
();
605
}
else
{
606
auto
pragmaTranslationContext
=
unitData
()->
translationContextIndex
();
607
context
=
stringAt
(*
pragmaTranslationContext
).
toUtf8
();
608
context
=
context
.
isEmpty
() ?
fileContext
() :
context
;
609
}
610
611
QByteArray
comment
=
stringAt
(
translation
.
commentIndex
).
toUtf8
();
612
QByteArray
text
=
stringAt
(
translation
.
stringIndex
).
toUtf8
();
613
return
QCoreApplication
::
translate
(
context
,
text
,
comment
,
translation
.
number
);
614
#
endif
615
}
616
617
Heap
::
Module
*
ExecutableCompilationUnit
::
module
()
const
618
{
619
if
(
const
Module
*
m
=
m_valueOrModule
.
as
<
QV4
::
Module
>())
620
return
m
->
d
();
621
return
nullptr
;
622
}
623
624
void
ExecutableCompilationUnit
::
setModule
(
Heap
::
Module
*
module
)
625
{
626
m_valueOrModule
=
module
;
627
}
628
629
}
// namespace QV4
630
631
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qstandardpaths_haiku.cpp:21
QV4
Definition
qjsvalue.h:23
QV4::dumpConstantTable
static void dumpConstantTable(const StaticValue *constants, uint count)
Definition
qv4executablecompilationunit.cpp:63
QV4::toString
static QString toString(QV4::ReturnedValue v)
Definition
qv4executablecompilationunit.cpp:48
qtdeclarative
src
qml
jsruntime
qv4executablecompilationunit.cpp
Generated on Mon Mar 10 2025 00:48:23 for Qt by
1.13.2