Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qv4codegen_p.h
Go to the documentation of this file.
1
// Copyright (C) 2017 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
5
#
ifndef
QV4CODEGEN_P_H
6
#
define
QV4CODEGEN_P_H
7
8
//
9
// W A R N I N G
10
// -------------
11
//
12
// This file is not part of the Qt API. It exists purely as an
13
// implementation detail. This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#
include
<
private
/
qqmljsastvisitor_p
.
h
>
20
#
include
<
private
/
qqmljsengine_p
.
h
>
21
#
include
<
private
/
qqmljsast_p
.
h
>
22
#
include
<
private
/
qqmljsdiagnosticmessage_p
.
h
>
23
#
include
<
private
/
qv4compiler_p
.
h
>
24
#
include
<
private
/
qv4compilercontext_p
.
h
>
25
#
include
<
private
/
qv4util_p
.
h
>
26
#
include
<
private
/
qv4bytecodegenerator_p
.
h
>
27
#
include
<
private
/
qv4calldata_p
.
h
>
28
29
#
include
<
QtCore
/
qsharedpointer
.
h
>
30
#
include
<
QtCore
/
qxpfunctional
.
h
>
31
32
#
include
<
stack
>
33
34
QT_BEGIN_NAMESPACE
35
36
namespace
QV4
{
37
38
namespace
Moth
{
39
struct
Instruction
;
40
}
41
42
namespace
CompiledData
{
43
struct
CompilationUnit
;
44
}
45
46
namespace
Compiler
{
47
48
struct
ControlFlow
;
49
struct
ControlFlowCatch
;
50
struct
ControlFlowFinally
;
51
52
class
Q_QML_COMPILER_EXPORT
CodegenWarningInterface
53
{
54
public
:
55
virtual
void
reportVarUsedBeforeDeclaration
(
const
QString
&
name
,
const
QString
&
fileName
,
56
QQmlJS
::
SourceLocation
declarationLocation
,
57
QQmlJS
::
SourceLocation
accessLocation
);
58
virtual
void
reportFunctionUsedBeforeDeclaration
(
const
QString
&
name
,
const
QString
&
fileName
,
59
QQmlJS
::
SourceLocation
declarationLocation
,
60
QQmlJS
::
SourceLocation
accessLocation
);
61
virtual
void
reportParserWarnings
(
const
QString
&
fileName
,
QQmlJS
::
SourceLocation
location
,
62
const
QString
&
message
)
63
{
64
qWarning
(
"%s:%d : %s"
,
qPrintable
(
fileName
),
location
.
startLine
,
qPrintable
(
message
));
65
}
66
67
virtual
void
reportSyntaxWarnings
(
QSpan
<
const
QQmlJS
::
DiagnosticMessage
>) { }
68
69
virtual
QQmlJS
::
AST
::
Visitor
*
unreachableVisitor
() {
return
nullptr
; }
70
virtual
~
CodegenWarningInterface
() =
default
;
71
};
72
73
inline
CodegenWarningInterface
*
defaultCodegenWarningInterface
()
74
{
75
static
CodegenWarningInterface iface;
76
return
&iface;
77
}
78
79
class
Q_QML_COMPILER_EXPORT
Codegen
:
protected
QQmlJS
::
AST
::
Visitor
80
{
81
protected
:
82
using
BytecodeGenerator
=
QV4
::
Moth
::
BytecodeGenerator
;
83
using
Instruction
=
QV4
::
Moth
::
Instruction
;
84
public
:
85
Codegen
(
QV4
::
Compiler
::
JSUnitGenerator
*
jsUnitGenerator
,
bool
strict
,
86
CodegenWarningInterface
*
iface
=
defaultCodegenWarningInterface
(),
87
bool
storeSourceLocations
=
false
);
88
89
static
bool
isNameGlobal
(
QAnyStringView
name
);
90
static
void
forEachGlobalName
(
qxp
::
function_ref
<
void
(
QLatin1StringView
)> &&
handler
);
91
92
void
generateFromProgram
(
93
const
QString
&
sourceCode
,
QQmlJS
::
AST
::
Program
*
ast
,
Module
*
module
,
94
ContextType
contextType
=
ContextType
::
Global
);
95
96
void
generateFromModule
(
const
QString
&
sourceCode
,
QQmlJS
::
AST
::
ESModule
*
ast
,
Module
*
module
);
97
void
generateFromModule
(
const
Value
&
value
,
Module
*
module
);
98
99
public
:
100
class
VolatileMemoryLocationScanner
;
101
class
VolatileMemoryLocations
{
102
friend
VolatileMemoryLocationScanner
;
103
bool
allVolatile
=
false
;
104
QList
<
QStringView
>
specificLocations
;
105
public
:
106
bool
isVolatile
(
QStringView
name
) {
107
if
(
allVolatile
)
108
return
true
;
109
return
specificLocations
.
contains
(
name
);
110
}
111
112
void
add
(
QStringView
name
) {
if
(!
allVolatile
)
specificLocations
.
append
(
name
); }
113
void
setAllVolatile
() {
allVolatile
=
true
; }
114
};
115
class
RValue
{
116
Codegen
*
codegen
;
117
enum
Type
{
118
Invalid
,
119
Accumulator
,
120
StackSlot
,
121
Const
122
}
type
;
123
union
{
124
Moth
::
StackSlot
theStackSlot
;
125
QV4
::
ReturnedValue
constant
;
126
};
127
128
public
:
129
static
RValue
fromStackSlot
(
Codegen
*
codegen
,
Moth
::
StackSlot
stackSlot
) {
130
RValue
r
;
131
r
.
codegen
=
codegen
;
132
r
.
type
=
StackSlot
;
133
r
.
theStackSlot
=
stackSlot
;
134
return
r
;
135
}
136
static
RValue
fromAccumulator
(
Codegen
*
codegen
) {
137
RValue
r
;
138
r
.
codegen
=
codegen
;
139
r
.
type
=
Accumulator
;
140
return
r
;
141
}
142
static
RValue
fromConst
(
Codegen
*
codegen
,
QV4
::
ReturnedValue
value
) {
143
RValue
r
;
144
r
.
codegen
=
codegen
;
145
r
.
type
=
Const
;
146
r
.
constant
=
value
;
147
return
r
;
148
}
149
150
bool
operator
==(
const
RValue
&
other
)
const
;
151
152
bool
isValid
()
const
{
return
type
!=
Invalid
; }
153
bool
isAccumulator
()
const
{
return
type
==
Accumulator
; }
154
bool
isStackSlot
()
const
{
return
type
==
StackSlot
; }
155
bool
isConst
()
const
{
return
type
==
Const
; }
156
157
Moth
::
StackSlot
stackSlot
()
const
{
158
Q_ASSERT
(
isStackSlot
());
159
return
theStackSlot
;
160
}
161
162
QV4
::
ReturnedValue
constantValue
()
const
{
163
Q_ASSERT
(
isConst
());
164
return
constant
;
165
}
166
167
Q_REQUIRED_RESULT
RValue
storeOnStack
()
const
;
168
void
loadInAccumulator
()
const
;
169
};
170
struct
Reference
{
171
enum
Type
{
172
Invalid
,
173
Accumulator
,
174
Super
,
175
SuperProperty
,
176
StackSlot
,
177
ScopedLocal
,
178
Name
,
179
Member
,
180
Subscript
,
181
Import
,
182
LastLValue
=
Import
,
183
Const
184
}
type
=
Invalid
;
185
186
bool
isLValue
()
const
{
return
!
isReadonly
&&
type
>
Accumulator
; }
187
188
Reference
(
Codegen
*
cg
,
Type
t
=
Invalid
) :
Reference
()
189
{
190
type
=
t
;
191
codegen
=
cg
;
192
}
193
194
Reference
(
const
QString
&
name
=
QString
()) :
195
constant
(0),
196
name
(
name
),
197
isArgOrEval
(
false
),
198
isReadonly
(
false
),
199
isReferenceToConst
(
false
),
200
requiresTDZCheck
(
false
),
201
subscriptRequiresTDZCheck
(
false
),
202
stackSlotIsLocalOrArgument
(
false
),
203
isVolatile
(
false
),
204
global
(
false
),
205
qmlGlobal
(
false
),
206
throwsReferenceError
(
false
),
207
subscriptLoadedForCall
(
false
),
208
isOptional
(
false
),
209
hasSavedCallBaseSlot
(
false
)
210
{}
211
212
Reference
(
const
Reference
&) =
default
;
213
Reference
(
Reference
&&) =
default
;
214
Reference
&
operator
=(
const
Reference
&) =
default
;
215
Reference
&
operator
=(
Reference
&&) =
default
;
216
217
bool
operator
==(
const
Reference
&
other
)
const
;
218
bool
operator
!=(
const
Reference
&
other
)
const
219
{
return
!(*
this
==
other
); }
220
221
bool
isValid
()
const
{
return
type
!=
Invalid
; }
222
bool
loadTriggersSideEffect
()
const
{
223
switch
(
type
) {
224
case
Name
:
225
case
Member
:
226
case
Subscript
:
227
case
SuperProperty
:
228
return
true
;
229
default
:
230
return
requiresTDZCheck
;
231
}
232
}
233
bool
isConstant
()
const
{
return
type
==
Const
; }
234
bool
isAccumulator
()
const
{
return
type
==
Accumulator
; }
235
bool
isSuper
()
const
{
return
type
==
Super
; }
236
bool
isSuperProperty
()
const
{
return
type
==
SuperProperty
; }
237
bool
isStackSlot
()
const
{
return
type
==
StackSlot
; }
238
bool
isRegister
()
const
{
239
return
isStackSlot
();
240
}
241
242
static
Reference
fromAccumulator
(
Codegen
*
cg
) {
243
return
Reference
(
cg
,
Accumulator
);
244
}
245
static
Reference
fromSuper
(
Codegen
*
cg
) {
246
return
Reference
(
cg
,
Super
);
247
}
248
static
Reference
fromStackSlot
(
Codegen
*
cg
,
int
tempIndex
= -1,
bool
isLocal
=
false
) {
249
Reference
r
(
cg
,
StackSlot
);
250
if
(
tempIndex
== -1)
251
tempIndex
=
cg
->
bytecodeGenerator
->
newRegister
();
252
r
.
theStackSlot
=
Moth
::
StackSlot
::
createRegister
(
tempIndex
);
253
r
.
stackSlotIsLocalOrArgument
=
isLocal
;
254
return
r
;
255
}
256
static
Reference
fromScopedLocal
(
Codegen
*
cg
,
int
index
,
int
scope
) {
257
Reference
r
(
cg
,
ScopedLocal
);
258
r
.
index
=
index
;
259
r
.
scope
=
scope
;
260
return
r
;
261
}
262
static
Reference
fromImport
(
Codegen
*
cg
,
int
index
) {
263
Reference
r
(
cg
,
Import
);
264
r
.
index
=
index
;
265
return
r
;
266
}
267
static
Reference
fromName
(
Codegen
*
cg
,
const
QString
&
name
) {
268
Reference
r
(
cg
,
Name
);
269
r
.
name
=
name
;
270
return
r
;
271
}
272
static
Reference
273
fromMember
(
const
Reference
&
baseRef
,
const
QString
&
name
,
274
QQmlJS
::
SourceLocation
sourceLocation
=
QQmlJS
::
SourceLocation
(),
275
bool
isOptional
=
false
,
276
std
::
vector
<
Moth
::
BytecodeGenerator
::
Jump
> *
optionalChainJumpsToPatch
=
nullptr
)
277
{
278
Q_ASSERT
(
baseRef
.
isValid
());
279
Reference
r
(
baseRef
.
codegen
,
Member
);
280
r
.
propertyBase
=
baseRef
.
asRValue
();
281
r
.
propertyNameIndex
=
r
.
codegen
->
registerString
(
name
);
282
r
.
requiresTDZCheck
=
baseRef
.
requiresTDZCheck
;
283
r
.
sourceLocation
=
sourceLocation
;
284
r
.
optionalChainJumpsToPatch
=
optionalChainJumpsToPatch
;
285
r
.
isOptional
=
isOptional
;
286
return
r
;
287
}
288
static
Reference
fromSuperProperty
(
const
Reference
&
property
) {
289
Q_ASSERT
(
property
.
isStackSlot
());
290
Reference
r
(
property
.
codegen
,
SuperProperty
);
291
r
.
property
=
property
.
stackSlot
();
292
r
.
subscriptRequiresTDZCheck
=
property
.
requiresTDZCheck
;
293
return
r
;
294
}
295
static
Reference
fromSubscript
(
const
Reference
&
baseRef
,
const
Reference
&
subscript
) {
296
Q_ASSERT
(
baseRef
.
isStackSlot
());
297
Reference
r
(
baseRef
.
codegen
,
Subscript
);
298
r
.
elementBase
=
baseRef
.
stackSlot
();
299
r
.
elementSubscript
=
subscript
.
asRValue
();
300
r
.
requiresTDZCheck
=
baseRef
.
requiresTDZCheck
;
301
r
.
subscriptRequiresTDZCheck
=
subscript
.
requiresTDZCheck
;
302
return
r
;
303
}
304
static
Reference
fromConst
(
Codegen
*
cg
,
QV4
::
ReturnedValue
constant
) {
305
Reference
r
(
cg
,
Const
);
306
r
.
constant
=
constant
;
307
r
.
isReadonly
=
true
;
308
return
r
;
309
}
310
static
Reference
fromThis
(
Codegen
*
cg
) {
311
Reference
r
=
fromStackSlot
(
cg
,
CallData
::
This
);
312
r
.
isReadonly
=
true
;
313
// ### Optimize this. Functions that are not derived constructors or arrow functions can't have an
314
// empty this object
315
r
.
requiresTDZCheck
=
true
;
316
return
r
;
317
}
318
319
RValue
asRValue
()
const
;
320
Reference
asLValue
()
const
;
321
322
Q_REQUIRED_RESULT
static
Reference
storeConstOnStack
(
Codegen
*
cg
,
QV4
::
ReturnedValue
constant
)
323
{
return
Reference
::
fromConst
(
cg
,
constant
).
storeOnStack
(); }
324
325
static
void
storeConstOnStack
(
Codegen
*
cg
,
QV4
::
ReturnedValue
constant
,
int
stackSlot
)
326
{
Reference
::
fromConst
(
cg
,
constant
).
storeOnStack
(
stackSlot
); }
327
328
Q_REQUIRED_RESULT
Reference
storeOnStack
()
const
;
329
void
storeOnStack
(
int
tempIndex
)
const
;
330
Q_REQUIRED_RESULT
Reference
storeRetainAccumulator
()
const
;
331
Reference
storeConsumeAccumulator
()
const
;
332
333
Q_REQUIRED_RESULT
Reference
baseObject
()
const
;
334
335
bool
storeWipesAccumulator
()
const
;
336
void
loadInAccumulator
()
const
;
337
338
int
nameAsIndex
()
const
{
339
Q_ASSERT
(
type
==
Name
);
340
return
codegen
->
registerString
(
name
);
341
}
342
343
Moth
::
StackSlot
stackSlot
()
const
{
344
if
(
Q_UNLIKELY
(!
isStackSlot
()))
345
Q_UNREACHABLE
();
346
return
theStackSlot
;
347
}
348
349
void
tdzCheck
()
const
350
{
351
if
(
isAccumulator
())
352
tdzCheck
(
requiresTDZCheck
,
throwsReferenceError
);
353
else
if
(
isStackSlot
())
354
tdzCheckStackSlot
(
stackSlot
(),
requiresTDZCheck
,
throwsReferenceError
);
355
}
356
357
void
checkTDZBeforeAssignment
()
const
;
358
359
union
{
360
Moth
::
StackSlot
theStackSlot
;
361
QV4
::
ReturnedValue
constant
;
362
struct
{
// Scoped arguments/Local
363
int
index
;
364
int
scope
;
365
};
366
struct
{
367
RValue
propertyBase
;
368
int
propertyNameIndex
;
369
};
370
struct
{
371
Moth
::
StackSlot
elementBase
;
372
union
{
373
RValue
elementSubscript
;
374
Moth
::
StackSlot
element
;
375
};
376
};
377
Moth
::
StackSlot
property
;
// super property
378
};
379
QString
name
;
380
Codegen
*
codegen
=
nullptr
;
381
382
quint32
isArgOrEval
:1;
383
quint32
isReadonly
:1;
384
quint32
isReferenceToConst
:1;
385
quint32
requiresTDZCheck
:1;
386
quint32
subscriptRequiresTDZCheck
:1;
387
quint32
stackSlotIsLocalOrArgument
:1;
388
quint32
isVolatile
:1;
389
quint32
global
:1;
390
quint32
qmlGlobal
:1;
391
quint32
throwsReferenceError
:1;
392
quint32
subscriptLoadedForCall
:1;
393
quint32
isOptional
: 1;
394
quint32
hasSavedCallBaseSlot
: 1;
395
QQmlJS
::
SourceLocation
sourceLocation
=
QQmlJS
::
SourceLocation
();
396
std
::
vector
<
Moth
::
BytecodeGenerator
::
Jump
> *
optionalChainJumpsToPatch
=
nullptr
;
397
int
savedCallBaseSlot
= -1;
398
int
savedCallPropertyNameIndex
= -1;
399
400
private
:
401
void
storeAccumulator
()
const
;
402
Reference
doStoreOnStack
(
int
tempIndex
)
const
;
403
void
tdzCheck
(
bool
requiresCheck
,
bool
throwsReferenceError
)
const
;
404
void
tdzCheckStackSlot
(
405
Moth
::
StackSlot
slot
,
bool
requiresCheck
,
bool
throwsReferenceError
)
const
;
406
};
407
408
struct
RegisterScope
{
409
RegisterScope
(
Codegen
*
cg
)
410
:
generator
(
cg
->
bytecodeGenerator
),
411
regCountForScope
(
generator
->
currentReg
) {}
412
~
RegisterScope
() {
413
generator
->
currentReg
=
regCountForScope
;
414
}
415
BytecodeGenerator
*
generator
;
416
int
regCountForScope
;
417
};
418
419
struct
ObjectPropertyValue
{
420
ObjectPropertyValue
() {}
421
422
Reference
rvalue
;
423
int
getter
= -1;
// index in _module->functions or -1 if not set
424
int
setter
= -1;
425
uint
keyAsIndex
=
UINT_MAX
;
426
427
bool
hasGetter
()
const
{
return
getter
>= 0; }
428
bool
hasSetter
()
const
{
return
setter
>= 0; }
429
};
430
protected
:
431
432
enum
Format
{
ex
,
cx
,
nx
};
433
class
Result
{
434
Reference
_result
;
435
436
const
BytecodeGenerator
::
Label
*
_iftrue
=
nullptr
;
437
const
BytecodeGenerator
::
Label
*
_iffalse
=
nullptr
;
438
Format
_format
=
ex
;
439
Format
_requested
;
440
bool
_trueBlockFollowsCondition
=
false
;
441
442
public
:
443
explicit
Result
(
const
QString
&
name
)
444
:
_result
(
name
)
445
,
_requested
(
ex
)
446
{}
447
448
explicit
Result
(
const
Reference
&
lrvalue
)
449
:
_result
(
lrvalue
)
450
,
_requested
(
ex
)
451
{}
452
453
explicit
Result
(
Format
requested
=
ex
)
454
:
_requested
(
requested
) {}
455
456
explicit
Result
(
const
BytecodeGenerator
::
Label
*
iftrue
,
457
const
BytecodeGenerator
::
Label
*
iffalse
,
458
bool
trueBlockFollowsCondition
)
459
:
_iftrue
(
iftrue
)
460
,
_iffalse
(
iffalse
)
461
,
_requested
(
cx
)
462
,
_trueBlockFollowsCondition
(
trueBlockFollowsCondition
)
463
{
464
Q_ASSERT
(
iftrue
);
465
Q_ASSERT
(
iffalse
);
466
}
467
468
const
BytecodeGenerator
::
Label
*
iftrue
()
const
{
469
Q_ASSERT
(
_requested
==
cx
);
470
return
_iftrue
;
471
}
472
473
const
BytecodeGenerator
::
Label
*
iffalse
()
const
{
474
Q_ASSERT
(
_requested
==
cx
);
475
return
_iffalse
;
476
}
477
478
Format
format
()
const
{
479
return
_format
;
480
}
481
482
bool
accept
(
Format
f
)
483
{
484
if
(
_requested
==
f
) {
485
_format
=
f
;
486
return
true
;
487
}
488
return
false
;
489
}
490
491
bool
trueBlockFollowsCondition
()
const
{
492
return
_trueBlockFollowsCondition
;
493
}
494
495
const
Reference
&
result
()
const
{
496
return
_result
;
497
}
498
499
void
setResult
(
const
Reference
&
result
) {
500
_result
=
result
;
501
}
502
503
void
setResult
(
Reference
&&
result
) {
504
_result
=
std
::
move
(
result
);
505
}
506
507
void
clearResultName
() {
508
_result
.
name
.
clear
();
509
}
510
};
511
512
void
enterContext
(
QQmlJS
::
AST
::
Node
*
node
);
513
int
leaveContext
();
514
public
:
515
Context
*
enterBlock
(
QQmlJS
::
AST
::
Node
*
node
);
516
int
leaveBlock
() {
return
leaveContext
(); }
517
protected
:
518
void
leaveLoop
();
519
520
enum
UnaryOperation
{
521
UPlus
,
522
UMinus
,
523
PreIncrement
,
524
PreDecrement
,
525
PostIncrement
,
526
PostDecrement
,
527
Not
,
528
Compl
529
};
530
531
Reference
unop
(
UnaryOperation
op
,
const
Reference
&
expr
);
532
533
void
addCJump
();
534
535
public
:
536
int
registerString
(
const
QString
&
name
) {
537
return
jsUnitGenerator
->
registerString
(
name
);
538
}
539
int
registerConstant
(
QV4
::
ReturnedValue
v
)
540
{
541
return
jsUnitGenerator
->
registerConstant
(
v
);
542
}
543
int
registerGetterLookup
(
int
nameIndex
,
JSUnitGenerator
::
LookupMode
mode
)
544
{
545
return
jsUnitGenerator
->
registerGetterLookup
(
nameIndex
,
mode
);
546
}
547
int
registerSetterLookup
(
int
nameIndex
)
548
{
549
return
jsUnitGenerator
->
registerSetterLookup
(
nameIndex
);
550
}
551
int
registerGlobalGetterLookup
(
int
nameIndex
,
JSUnitGenerator
::
LookupMode
mode
)
552
{
553
return
jsUnitGenerator
->
registerGlobalGetterLookup
(
nameIndex
,
mode
);
554
}
555
int
registerQmlContextPropertyGetterLookup
(
int
nameIndex
,
JSUnitGenerator
::
LookupMode
mode
)
556
{
557
return
jsUnitGenerator
->
registerQmlContextPropertyGetterLookup
(
nameIndex
,
mode
);
558
}
559
560
// Returns index in _module->functions
561
int
defineFunction
(
const
QString
&
name
,
QQmlJS
::
AST
::
Node
*
ast
,
562
QQmlJS
::
AST
::
FormalParameterList
*
formals
,
563
QQmlJS
::
AST
::
StatementList
*
body
);
564
565
protected
:
566
void
statement
(
QQmlJS
::
AST
::
Statement
*
ast
);
567
void
statement
(
QQmlJS
::
AST
::
ExpressionNode
*
ast
);
568
void
condition
(
QQmlJS
::
AST
::
ExpressionNode
*
ast
,
const
BytecodeGenerator
::
Label
*
iftrue
,
569
const
BytecodeGenerator
::
Label
*
iffalse
,
570
bool
trueBlockFollowsCondition
);
571
572
inline
Reference
expression
(
QQmlJS
::
AST
::
ExpressionNode
*
ast
,
const
QString
&
name
=
QString
())
573
{
574
if
(!
ast
||
hasError
())
575
return
Reference
();
576
577
pushExpr
(
name
);
578
ast
->
accept
(
this
);
579
return
popResult
();
580
}
581
582
inline
void
accept
(
QQmlJS
::
AST
::
Node
*
node
)
583
{
584
if
(!
hasError
() &&
node
)
585
node
->
accept
(
this
);
586
}
587
588
void
program
(
QQmlJS
::
AST
::
Program
*
ast
);
589
void
statementList
(
QQmlJS
::
AST
::
StatementList
*
ast
);
590
void
variableDeclaration
(
QQmlJS
::
AST
::
PatternElement
*
ast
);
591
void
variableDeclarationList
(
QQmlJS
::
AST
::
VariableDeclarationList
*
ast
);
592
593
Reference
targetForPatternElement
(
QQmlJS
::
AST
::
PatternElement
*
p
);
594
Reference
referenceForFormalParameter
(
int
argIndex
);
595
void
initializeAndDestructureBindingElement
(
QQmlJS
::
AST
::
PatternElement
*
e
,
const
Reference
&
baseRef
=
Reference
(),
bool
isDefinition
=
false
);
596
void
destructurePropertyList
(
const
Reference
&
object
,
QQmlJS
::
AST
::
PatternPropertyList
*
bindingList
,
bool
isDefinition
=
false
);
597
void
destructureElementList
(
const
Reference
&
array
,
QQmlJS
::
AST
::
PatternElementList
*
bindingList
,
bool
isDefinition
=
false
);
598
void
destructurePattern
(
QQmlJS
::
AST
::
Pattern
*
p
,
const
Reference
&
rhs
);
599
600
Reference
referenceForPropertyName
(
const
Codegen
::
Reference
&
object
,
QQmlJS
::
AST
::
PropertyName
*
name
);
601
602
void
emitReturn
(
const
Reference
&
expr
);
603
604
// nodes
605
bool
visit
(
QQmlJS
::
AST
::
ArgumentList
*
ast
)
override
;
606
bool
visit
(
QQmlJS
::
AST
::
CaseBlock
*
ast
)
override
;
607
bool
visit
(
QQmlJS
::
AST
::
CaseClause
*
ast
)
override
;
608
bool
visit
(
QQmlJS
::
AST
::
CaseClauses
*
ast
)
override
;
609
bool
visit
(
QQmlJS
::
AST
::
Catch
*
ast
)
override
;
610
bool
visit
(
QQmlJS
::
AST
::
DefaultClause
*
ast
)
override
;
611
bool
visit
(
QQmlJS
::
AST
::
Elision
*
ast
)
override
;
612
bool
visit
(
QQmlJS
::
AST
::
Finally
*
ast
)
override
;
613
bool
visit
(
QQmlJS
::
AST
::
FormalParameterList
*
ast
)
override
;
614
bool
visit
(
QQmlJS
::
AST
::
Program
*
ast
)
override
;
615
bool
visit
(
QQmlJS
::
AST
::
StatementList
*
ast
)
override
;
616
bool
visit
(
QQmlJS
::
AST
::
UiArrayMemberList
*
ast
)
override
;
617
bool
visit
(
QQmlJS
::
AST
::
UiImport
*
ast
)
override
;
618
bool
visit
(
QQmlJS
::
AST
::
UiHeaderItemList
*
ast
)
override
;
619
bool
visit
(
QQmlJS
::
AST
::
UiPragmaValueList
*
ast
)
override
;
620
bool
visit
(
QQmlJS
::
AST
::
UiPragma
*
ast
)
override
;
621
bool
visit
(
QQmlJS
::
AST
::
UiObjectInitializer
*
ast
)
override
;
622
bool
visit
(
QQmlJS
::
AST
::
UiObjectMemberList
*
ast
)
override
;
623
bool
visit
(
QQmlJS
::
AST
::
UiParameterList
*
ast
)
override
;
624
bool
visit
(
QQmlJS
::
AST
::
UiProgram
*
ast
)
override
;
625
bool
visit
(
QQmlJS
::
AST
::
UiQualifiedId
*
ast
)
override
;
626
bool
visit
(
QQmlJS
::
AST
::
VariableDeclarationList
*
ast
)
override
;
627
628
bool
visit
(
QQmlJS
::
AST
::
PatternElement
*
ast
)
override
;
629
bool
visit
(
QQmlJS
::
AST
::
PatternElementList
*
ast
)
override
;
630
bool
visit
(
QQmlJS
::
AST
::
PatternProperty
*
ast
)
override
;
631
bool
visit
(
QQmlJS
::
AST
::
PatternPropertyList
*
ast
)
override
;
632
633
bool
visit
(
QQmlJS
::
AST
::
ExportDeclaration
*
ast
)
override
;
634
635
bool
visit
(
QQmlJS
::
AST
::
TypeAnnotation
*
ast
)
override
;
636
637
// expressions
638
bool
visit
(
QQmlJS
::
AST
::
ArrayPattern
*
ast
)
override
;
639
bool
visit
(
QQmlJS
::
AST
::
ArrayMemberExpression
*
ast
)
override
;
640
bool
visit
(
QQmlJS
::
AST
::
BinaryExpression
*
ast
)
override
;
641
bool
visit
(
QQmlJS
::
AST
::
CallExpression
*
ast
)
override
;
642
void
endVisit
(
QQmlJS
::
AST
::
CallExpression
*
ast
)
override
;
643
bool
visit
(
QQmlJS
::
AST
::
CommaExpression
*
ast
)
override
;
644
bool
visit
(
QQmlJS
::
AST
::
ConditionalExpression
*
ast
)
override
;
645
bool
visit
(
QQmlJS
::
AST
::
DeleteExpression
*
ast
)
override
;
646
void
endVisit
(
QQmlJS
::
AST
::
DeleteExpression
*
ast
)
override
;
647
bool
visit
(
QQmlJS
::
AST
::
FalseLiteral
*
ast
)
override
;
648
bool
visit
(
QQmlJS
::
AST
::
SuperLiteral
*
ast
)
override
;
649
bool
visit
(
QQmlJS
::
AST
::
FieldMemberExpression
*
ast
)
override
;
650
void
endVisit
(
QQmlJS
::
AST
::
FieldMemberExpression
*
ast
)
override
;
651
bool
visit
(
QQmlJS
::
AST
::
TaggedTemplate
*
ast
)
override
;
652
bool
visit
(
QQmlJS
::
AST
::
FunctionExpression
*
ast
)
override
;
653
bool
visit
(
QQmlJS
::
AST
::
IdentifierExpression
*
ast
)
override
;
654
bool
visit
(
QQmlJS
::
AST
::
NestedExpression
*
ast
)
override
;
655
bool
visit
(
QQmlJS
::
AST
::
NewExpression
*
ast
)
override
;
656
bool
visit
(
QQmlJS
::
AST
::
NewMemberExpression
*
ast
)
override
;
657
bool
visit
(
QQmlJS
::
AST
::
NotExpression
*
ast
)
override
;
658
bool
visit
(
QQmlJS
::
AST
::
NullExpression
*
ast
)
override
;
659
bool
visit
(
QQmlJS
::
AST
::
NumericLiteral
*
ast
)
override
;
660
bool
visit
(
QQmlJS
::
AST
::
ObjectPattern
*
ast
)
override
;
661
bool
visit
(
QQmlJS
::
AST
::
PostDecrementExpression
*
ast
)
override
;
662
bool
visit
(
QQmlJS
::
AST
::
PostIncrementExpression
*
ast
)
override
;
663
bool
visit
(
QQmlJS
::
AST
::
PreDecrementExpression
*
ast
)
override
;
664
bool
visit
(
QQmlJS
::
AST
::
PreIncrementExpression
*
ast
)
override
;
665
bool
visit
(
QQmlJS
::
AST
::
RegExpLiteral
*
ast
)
override
;
666
bool
visit
(
QQmlJS
::
AST
::
StringLiteral
*
ast
)
override
;
667
bool
visit
(
QQmlJS
::
AST
::
TemplateLiteral
*
ast
)
override
;
668
bool
visit
(
QQmlJS
::
AST
::
ThisExpression
*
ast
)
override
;
669
bool
visit
(
QQmlJS
::
AST
::
TildeExpression
*
ast
)
override
;
670
bool
visit
(
QQmlJS
::
AST
::
TrueLiteral
*
ast
)
override
;
671
bool
visit
(
QQmlJS
::
AST
::
TypeOfExpression
*
ast
)
override
;
672
bool
visit
(
QQmlJS
::
AST
::
UnaryMinusExpression
*
ast
)
override
;
673
bool
visit
(
QQmlJS
::
AST
::
UnaryPlusExpression
*
ast
)
override
;
674
bool
visit
(
QQmlJS
::
AST
::
VoidExpression
*
ast
)
override
;
675
bool
visit
(
QQmlJS
::
AST
::
FunctionDeclaration
*
ast
)
override
;
676
bool
visit
(
QQmlJS
::
AST
::
YieldExpression
*
ast
)
override
;
677
bool
visit
(
QQmlJS
::
AST
::
ClassExpression
*
ast
)
override
;
678
bool
visit
(
QQmlJS
::
AST
::
ClassDeclaration
*
ast
)
override
;
679
680
// statements
681
bool
visit
(
QQmlJS
::
AST
::
Block
*
ast
)
override
;
682
bool
visit
(
QQmlJS
::
AST
::
BreakStatement
*
ast
)
override
;
683
bool
visit
(
QQmlJS
::
AST
::
ContinueStatement
*
ast
)
override
;
684
bool
visit
(
QQmlJS
::
AST
::
DebuggerStatement
*
ast
)
override
;
685
bool
visit
(
QQmlJS
::
AST
::
DoWhileStatement
*
ast
)
override
;
686
bool
visit
(
QQmlJS
::
AST
::
EmptyStatement
*
ast
)
override
;
687
bool
visit
(
QQmlJS
::
AST
::
ExpressionStatement
*
ast
)
override
;
688
bool
visit
(
QQmlJS
::
AST
::
ForEachStatement
*
ast
)
override
;
689
bool
visit
(
QQmlJS
::
AST
::
ForStatement
*
ast
)
override
;
690
bool
visit
(
QQmlJS
::
AST
::
IfStatement
*
ast
)
override
;
691
bool
visit
(
QQmlJS
::
AST
::
LabelledStatement
*
ast
)
override
;
692
bool
visit
(
QQmlJS
::
AST
::
ReturnStatement
*
ast
)
override
;
693
bool
visit
(
QQmlJS
::
AST
::
SwitchStatement
*
ast
)
override
;
694
bool
visit
(
QQmlJS
::
AST
::
ThrowStatement
*
ast
)
override
;
695
bool
visit
(
QQmlJS
::
AST
::
TryStatement
*
ast
)
override
;
696
bool
visit
(
QQmlJS
::
AST
::
VariableStatement
*
ast
)
override
;
697
bool
visit
(
QQmlJS
::
AST
::
WhileStatement
*
ast
)
override
;
698
bool
visit
(
QQmlJS
::
AST
::
WithStatement
*
ast
)
override
;
699
700
// ui object members
701
bool
visit
(
QQmlJS
::
AST
::
UiArrayBinding
*
ast
)
override
;
702
bool
visit
(
QQmlJS
::
AST
::
UiObjectBinding
*
ast
)
override
;
703
bool
visit
(
QQmlJS
::
AST
::
UiObjectDefinition
*
ast
)
override
;
704
bool
visit
(
QQmlJS
::
AST
::
UiPublicMember
*
ast
)
override
;
705
bool
visit
(
QQmlJS
::
AST
::
UiScriptBinding
*
ast
)
override
;
706
bool
visit
(
QQmlJS
::
AST
::
UiSourceElement
*
ast
)
override
;
707
708
bool
throwSyntaxErrorOnEvalOrArgumentsInStrictMode
(
const
Reference
&
r
,
709
const
QQmlJS
::
SourceLocation
&
loc
);
710
virtual
void
throwSyntaxError
(
const
QQmlJS
::
SourceLocation
&
loc
,
const
QString
&
detail
);
711
virtual
void
throwReferenceError
(
const
QQmlJS
::
SourceLocation
&
loc
,
const
QString
&
detail
);
712
void
throwRecursionDepthError
()
override
713
{
714
throwSyntaxError
(
QQmlJS
::
SourceLocation
(),
715
QStringLiteral
(
"Maximum statement or expression depth exceeded"
));
716
}
717
718
public
:
719
enum
ErrorType
{
720
NoError
,
721
SyntaxError
,
722
ReferenceError
723
};
724
725
ErrorType
errorType
()
const
{
return
_errorType
; }
726
bool
hasError
()
const
{
return
_errorType
!=
NoError
; }
727
QQmlJS
::
DiagnosticMessage
error
()
const
;
728
QUrl
url
()
const
;
729
730
Reference
binopHelper
(
QQmlJS
::
AST
::
BinaryExpression
*
ast
,
QSOperator
::
Op
oper
,
Reference
&
left
,
731
Reference
&
right
);
732
Reference
jumpBinop
(
QSOperator
::
Op
oper
,
Reference
&
left
,
Reference
&
right
);
733
struct
Arguments
{
int
argc
;
int
argv
;
bool
hasSpread
; };
734
Arguments
pushArgs
(
QQmlJS
::
AST
::
ArgumentList
*
args
);
735
void
handleCall
(
Reference
&
base
,
Arguments
calldata
,
int
slotForFunction
,
int
slotForThisObject
,
bool
optional
=
false
);
736
737
Arguments
pushTemplateArgs
(
QQmlJS
::
AST
::
TemplateLiteral
*
args
);
738
bool
handleTaggedTemplate
(
Reference
base
,
QQmlJS
::
AST
::
TaggedTemplate
*
ast
);
739
void
createTemplateObject
(
QQmlJS
::
AST
::
TemplateLiteral
*
t
);
740
741
void
setUseFastLookups
(
bool
b
) {
useFastLookups
=
b
; }
742
743
void
handleTryCatch
(
QQmlJS
::
AST
::
TryStatement
*
ast
);
744
void
handleTryFinally
(
QQmlJS
::
AST
::
TryStatement
*
ast
);
745
746
747
Reference
referenceForName
(
748
const
QString
&
name
,
bool
lhs
,
749
const
QQmlJS
::
SourceLocation
&
accessLocation
=
QQmlJS
::
SourceLocation
());
750
751
QQmlRefPointer
<
QV4
::
CompiledData
::
CompilationUnit
>
generateCompilationUnit
(
752
bool
generateUnitData
=
true
);
753
static
QQmlRefPointer
<
QV4
::
CompiledData
::
CompilationUnit
>
compileModule
(
754
bool
debugMode
,
const
QString
&
url
,
const
QString
&
sourceCode
,
755
const
QDateTime
&
sourceTimeStamp
,
QList
<
QQmlJS
::
DiagnosticMessage
> *
diagnostics
);
756
757
static
const
QV4
::
CompiledData
::
Unit
*
generateNativeModuleUnitData
(
758
bool
debugMode
,
const
QString
&
url
,
const
QV4
::
Value
&
value
);
759
760
Context
*
currentContext
()
const
{
return
_context
; }
761
BytecodeGenerator
*
generator
()
const
{
return
bytecodeGenerator
; }
762
763
void
loadClosure
(
int
index
);
764
765
Module
*
module
()
const
{
return
_module
; }
766
767
BytecodeGenerator
::
Label
returnLabel
() {
768
if
(!
_returnLabel
)
769
_returnLabel
=
new
BytecodeGenerator
::
Label
(
bytecodeGenerator
->
newLabel
());
770
return
*
_returnLabel
;
771
}
772
773
protected
:
774
friend
class
ScanFunctions
;
775
friend
struct
ControlFlow
;
776
friend
struct
ControlFlowCatch
;
777
friend
struct
ControlFlowFinally
;
778
779
inline
void
setExprResult
(
const
Reference
&
result
) {
m_expressions
.
back
().
setResult
(
result
); }
780
inline
void
setExprResult
(
Reference
&&
result
) {
m_expressions
.
back
().
setResult
(
std
::
move
(
result
)); }
781
inline
Reference
exprResult
()
const
{
return
m_expressions
.
back
().
result
(); }
782
inline
void
clearExprResultName
() {
m_expressions
.
back
().
clearResultName
(); }
783
784
inline
bool
exprAccept
(
Format
f
) {
return
m_expressions
.
back
().
accept
(
f
); }
785
786
inline
const
Result
&
currentExpr
()
const
{
return
m_expressions
.
back
(); }
787
788
inline
void
pushExpr
(
Result
&&
expr
) {
m_expressions
.
push_back
(
std
::
move
(
expr
)); }
789
inline
void
pushExpr
(
const
Result
&
expr
) {
m_expressions
.
push_back
(
expr
); }
790
inline
void
pushExpr
(
const
QString
&
name
=
QString
()) {
m_expressions
.
emplace_back
(
name
); }
791
792
inline
Result
popExpr
()
793
{
794
const
Result
result
=
m_expressions
.
back
();
795
m_expressions
.
pop_back
();
796
return
result
;
797
}
798
799
inline
Reference
popResult
() {
800
const
Reference
result
=
m_expressions
.
back
().
result
();
801
m_expressions
.
pop_back
();
802
return
result
;
803
}
804
805
std
::
vector
<
Result
>
m_expressions
;
806
VolatileMemoryLocations
_volatileMemoryLocations
;
807
Module
*
_module
;
808
int
_returnAddress
;
809
Context
*
_context
;
810
Context
*
_functionContext
=
nullptr
;
811
QQmlJS
::
AST
::
LabelledStatement
*
_labelledStatement
;
812
QV4
::
Compiler
::
JSUnitGenerator
*
jsUnitGenerator
;
813
BytecodeGenerator
*
bytecodeGenerator
=
nullptr
;
814
Moth
::
BytecodeGenerator
::
Label
*
_returnLabel
=
nullptr
;
815
bool
_strictMode
;
816
bool
useFastLookups
=
true
;
817
bool
requiresReturnValue
=
false
;
818
bool
insideSwitch
=
false
;
819
bool
inFormalParameterList
=
false
;
820
bool
functionEndsWithReturn
=
false
;
821
bool
_tailCallsAreAllowed
=
true
;
822
bool
storeSourceLocations
=
false
;
823
824
struct
OptionalChainState
825
{
826
QQmlJS
::
AST
::
Node
*
tailNodeOfChain
=
nullptr
;
827
std
::
vector
<
Moth
::
BytecodeGenerator
::
Jump
>
jumpsToPatch
;
828
bool
actuallyHasOptionals
=
false
;
829
};
830
using
OptionalChainStates
=
std
::
stack
<
OptionalChainState
,
std
::
vector
<
OptionalChainState
>>;
831
832
QSet
<
QQmlJS
::
AST
::
Node
*>
m_seenOptionalChainNodes
;
833
OptionalChainStates
*
m_optionalChainsStates
=
nullptr
;
834
835
ControlFlow
*
controlFlow
=
nullptr
;
836
837
bool
_fileNameIsUrl
;
838
ErrorType
_errorType
=
NoError
;
839
QQmlJS
::
DiagnosticMessage
_error
;
840
CodegenWarningInterface
*
_interface
;
841
842
class
TailCallBlocker
843
{
844
public
:
845
TailCallBlocker
(
Codegen
*
cg
,
bool
onoff
=
false
)
846
:
_cg
(
cg
)
847
,
_saved
(
_cg
->
_tailCallsAreAllowed
)
848
,
_onoff
(
onoff
)
849
{
_cg
->
_tailCallsAreAllowed
=
onoff
; }
850
851
~
TailCallBlocker
()
852
{
_cg
->
_tailCallsAreAllowed
=
_saved
; }
853
854
void
unblock
()
const
855
{
_cg
->
_tailCallsAreAllowed
=
_saved
; }
856
857
void
reblock
()
const
858
{
_cg
->
_tailCallsAreAllowed
=
_onoff
; }
859
860
private
:
861
Codegen
*
_cg
;
862
bool
_saved
;
863
bool
_onoff
;
864
};
865
866
private
:
867
Q_DISABLE_COPY
(
Codegen
)
868
VolatileMemoryLocations
scanVolatileMemoryLocations
(
QQmlJS
::
AST
::
Node
*
ast
);
869
void
handleConstruct
(
const
Reference
&
base
,
QQmlJS
::
AST
::
ArgumentList
*
args
);
870
void
throwError
(
ErrorType
errorType
,
const
QQmlJS
::
SourceLocation
&
loc
,
871
const
QString
&
detail
);
872
bool
traverseOptionalChain
(
QQmlJS
::
AST
::
Node
*
node
);
873
void
optionalChainFinalizer
(
const
Reference
&
expressionResult
,
bool
tailOfChain
,
874
bool
isDeleteExpression
=
false
);
875
Reference
loadSubscriptForCall
(
const
Reference
&
base
);
876
void
generateThrowException
(
const
QString
&
type
,
const
QString
&
text
=
QString
());
877
};
878
879
}
880
881
}
882
883
QT_END_NAMESPACE
884
885
#
endif
// QV4CODEGEN_P_H
QV4::Compiler::Codegen::VolatileMemoryLocationScanner
Definition
qv4codegen.cpp:4344
QV4::Compiler::Codegen::VolatileMemoryLocationScanner::throwRecursionDepthError
void throwRecursionDepthError() override
Definition
qv4codegen.cpp:4418
QV4::Compiler::Codegen::VolatileMemoryLocationScanner::VolatileMemoryLocationScanner
VolatileMemoryLocationScanner(Codegen *parent)
Definition
qv4codegen.cpp:4349
QV4::Compiler::Codegen::VolatileMemoryLocationScanner::scan
Codegen::VolatileMemoryLocations scan(AST::Node *s)
Definition
qv4codegen.cpp:4354
QV4::Compiler::Codegen::VolatileMemoryLocationScanner::visit
bool visit(ArrayMemberExpression *) override
Definition
qv4codegen.cpp:4360
QV4::Compiler::CodegenWarningInterface
Definition
qv4codegen_p.h:53
QV4::Compiler::Codegen
Definition
qv4codegen_p.h:80
QV4::CompiledData
Definition
qv4compileddata.cpp:22
QV4::Compiler
Definition
qv4compiler_p.h:40
QV4::Compiler::defaultCodegenWarningInterface
CodegenWarningInterface * defaultCodegenWarningInterface()
Definition
qv4codegen_p.h:73
QV4::Moth
Definition
qv4codegen_p.h:38
QV4
Definition
qjsvalue.h:24
Q_STATIC_LOGGING_CATEGORY
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
completionStatement
static Node * completionStatement(StatementList *list)
Definition
qv4codegen.cpp:548
completionState
static CompletionState completionState(StatementList *list)
Definition
qv4codegen.cpp:527
baseOp
static QSOperator::Op baseOp(int op)
Definition
qv4codegen.cpp:1412
CompletionState
CompletionState
Definition
qv4codegen.cpp:521
CompletionState::Empty
@ Empty
Definition
qv4codegen.cpp:522
CompletionState::EmptyAbrupt
@ EmptyAbrupt
Definition
qv4codegen.cpp:523
CompletionState::NonEmpty
@ NonEmpty
Definition
qv4codegen.cpp:524
endsWithReturn
static bool endsWithReturn(Module *module, Node *node)
Definition
qv4codegen.cpp:3411
setJumpOutLocation
static void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGenerator, const Statement *body, const SourceLocation &fallback)
Definition
qv4codegen.cpp:62
s_globalNames
static constexpr const QLatin1StringView s_globalNames[]
Definition
qv4codegen.cpp:119
QV4::CompiledData::CompilationUnit::IdToObjectMap
QMap< int, int > IdToObjectMap
Definition
qv4compileddata_p.h:1531
QV4::Compiler::ControlFlowCatch
Definition
qv4compilercontrolflow_p.h:281
QV4::Compiler::ControlFlowFinally
Definition
qv4compilercontrolflow_p.h:342
QV4::Compiler::ControlFlow
Definition
qv4compilercontrolflow_p.h:29
QV4::Moth::Instruction
Definition
qv4instr_moth_p.h:651
qtdeclarative
src
qml
compiler
qv4codegen_p.h
Generated on
for Qt by
1.18.0