Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmljscompilepass_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QQMLJSCOMPILEPASS_P_H
5#define QQMLJSCOMPILEPASS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16
17
18#include <private/qqmljslogger_p.h>
19#include <private/qqmljsregistercontent_p.h>
20#include <private/qqmljsscope_p.h>
21#include <private/qqmljstyperesolver_p.h>
22#include <private/qv4bytecodehandler_p.h>
23#include <private/qv4compiler_p.h>
24#include <private/qflatmap_p.h>
25
27
29{
30 Q_DISABLE_COPY_MOVE(QQmlJSCompilePass)
31public:
37 };
38
40
42 {
44 bool canMove = false;
46
47 private:
48 friend bool operator==(const VirtualRegister &a, const VirtualRegister &b)
49 {
50 return a.content == b.content && a.canMove == b.canMove
51 && a.affectedBySideEffects == b.affectedBySideEffects;
52 }
53 };
54
55 // map from register index to expected type
57
59 {
60 // Registers explicit read as part of the instruction.
62
63 // Registers that have to be converted for future instructions after a jump.
65
68 bool hasSideEffects = false;
69 bool isRename = false;
70 };
71
73
74 struct Function
75 {
83 bool isSignalHandler = false;
84 bool isQPropertyBinding = false;
85 bool isProperty = false;
86 bool isFullyTyped = false;
87 };
88
89 struct State
90 {
92
94 {
97 return it.value().content;
98 };
99
101 {
102 Q_ASSERT(m_changedRegisterIndex == Accumulator);
103 return m_changedRegister;
104 };
105
106 void setRegister(int registerIndex, QQmlJSRegisterContent content)
107 {
108 m_changedRegister = std::move(content);
109 m_changedRegisterIndex = registerIndex;
110 }
111
113 {
114 m_changedRegisterIndex = InvalidRegister;
115 m_changedRegister = QQmlJSRegisterContent();
116 }
117
118 int changedRegisterIndex() const { return m_changedRegisterIndex; }
119 const QQmlJSRegisterContent &changedRegister() const { return m_changedRegister; }
120
121 void addReadRegister(int registerIndex, const QQmlJSRegisterContent &reg)
122 {
123 Q_ASSERT(isRename() || reg.isConversion());
124 const VirtualRegister &source = registers[registerIndex];
125 VirtualRegister &target = m_readRegisters[registerIndex];
126 target.content = reg;
127 target.canMove = source.canMove;
128 target.affectedBySideEffects = source.affectedBySideEffects;
129 }
130
132 {
134 }
135
136 VirtualRegisters takeReadRegisters() const { return std::move(m_readRegisters); }
138 {
139 m_readRegisters = std::move(readReagisters);
140 }
141
142 QQmlJSRegisterContent readRegister(int registerIndex) const
143 {
144 Q_ASSERT(m_readRegisters.contains(registerIndex));
145 return m_readRegisters[registerIndex].content;
146 }
147
148 bool canMoveReadRegister(int registerIndex) const
149 {
150 auto it = m_readRegisters.find(registerIndex);
151 return it != m_readRegisters.end() && it->second.canMove;
152 }
153
154 bool isRegisterAffectedBySideEffects(int registerIndex) const
155 {
156 auto it = m_readRegisters.find(registerIndex);
157 return it != m_readRegisters.end() && it->second.affectedBySideEffects;
158 }
159
161 {
163 }
164
165 bool readsRegister(int registerIndex) const
166 {
167 return m_readRegisters.contains(registerIndex);
168 }
169
170 bool hasSideEffects() const { return m_hasSideEffects; }
172 m_hasSideEffects = hasSideEffects;
173 if (!hasSideEffects)
174 return;
175
176 for (auto it = registers.begin(), end = registers.end(); it != end; ++it)
177 it.value().affectedBySideEffects = true;
178 }
179
180 bool isRename() const { return m_isRename; }
181 void setIsRename(bool isRename) { m_isRename = isRename; }
182
184 {
185 Q_ASSERT(m_isRename);
186 Q_ASSERT(m_readRegisters.size() == 1);
187 return m_readRegisters.begin().key();
188 }
189
190 private:
191 VirtualRegisters m_readRegisters;
192 QQmlJSRegisterContent m_changedRegister;
193 int m_changedRegisterIndex = InvalidRegister;
194 bool m_hasSideEffects = false;
195 bool m_isRename = false;
196 };
197
199 const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger)
200 : m_jsUnitGenerator(jsUnitGenerator)
201 , m_typeResolver(typeResolver)
202 , m_logger(logger)
203 {}
204
205protected:
209
210 const Function *m_function = nullptr;
212
214 {
216 }
217
218 bool isArgument(int registerIndex) const
219 {
220 return registerIndex >= FirstArgument && registerIndex < firstRegisterIndex();
221 }
222
223 QQmlJSRegisterContent argumentType(int registerIndex) const
224 {
225 Q_ASSERT(isArgument(registerIndex));
226 return m_function->argumentTypes[registerIndex - FirstArgument];
227 }
228
229
230 State initialState(const Function *function)
231 {
232 State state;
233 for (int i = 0, end = function->argumentTypes.size(); i < end; ++i) {
234 state.registers[FirstArgument + i].content = function->argumentTypes.at(i);
235 Q_ASSERT(state.registers[FirstArgument + i].content.isValid());
236 }
237 for (int i = 0, end = function->registerTypes.size(); i != end; ++i)
238 state.registers[firstRegisterIndex() + i].content = function->registerTypes[i];
239 return state;
240 }
241
243 const State &oldState, const InstructionAnnotations &annotations)
244 {
246
247 const auto instruction = annotations.find(currentInstructionOffset());
248 newState.registers = oldState.registers;
249
250 // Usually the initial accumulator type is the output of the previous instruction, but ...
251 if (oldState.changedRegisterIndex() != InvalidRegister) {
252 newState.registers[oldState.changedRegisterIndex()].affectedBySideEffects = false;
253 newState.registers[oldState.changedRegisterIndex()].content
254 = oldState.changedRegister();
255 }
256
257 if (instruction == annotations.constEnd())
258 return newState;
259
260 newState.setHasSideEffects(instruction->second.hasSideEffects);
261 newState.setReadRegisters(instruction->second.readRegisters);
262 newState.setIsRename(instruction->second.isRename);
263
264 for (auto it = instruction->second.typeConversions.begin(),
265 end = instruction->second.typeConversions.end(); it != end; ++it) {
266 Q_ASSERT(it.key() != InvalidRegister);
267 newState.registers[it.key()] = it.value();
268 }
269
270 if (instruction->second.changedRegisterIndex != InvalidRegister) {
271 newState.setRegister(instruction->second.changedRegisterIndex,
272 instruction->second.changedRegister);
273 }
274
275 return newState;
276 }
277
278 QQmlJS::SourceLocation sourceLocation(int instructionOffset) const
279 {
282 const auto &entries = m_function->sourceLocations->entries;
283 auto item = std::lower_bound(entries.begin(), entries.end(), instructionOffset,
284 [](auto entry, uint offset) { return entry.offset < offset; });
285
286 Q_ASSERT(item != entries.end());
287 return item->location;
288 }
289
291 {
293 }
294
295 void setError(const QString &message, int instructionOffset)
296 {
298 if (m_error->isValid())
299 return;
301 m_error->loc = sourceLocation(instructionOffset);
302 }
303
305 {
307 }
308
310 {
312 switch (type) {
313 case Type::PopContext:
314 case Type::PopScriptContext:
315 case Type::CreateCallContext:
316 case Type::CreateCallContext_Wide:
317 case Type::PushCatchContext:
318 case Type::PushCatchContext_Wide:
319 case Type::PushWithContext:
320 case Type::PushWithContext_Wide:
321 case Type::PushBlockContext:
322 case Type::PushBlockContext_Wide:
323 case Type::CloneBlockContext:
324 case Type::CloneBlockContext_Wide:
325 case Type::PushScriptContext:
326 case Type::PushScriptContext_Wide:
327 return true;
328 default:
329 break;
330 }
331 return false;
332 }
333
334 // Stub out all the methods so that passes can choose to only implement part of them.
335 void generate_Add(int) override {}
336 void generate_As(int) override {}
337 void generate_BitAnd(int) override {}
338 void generate_BitAndConst(int) override {}
339 void generate_BitOr(int) override {}
340 void generate_BitOrConst(int) override {}
341 void generate_BitXor(int) override {}
342 void generate_BitXorConst(int) override {}
343 void generate_CallGlobalLookup(int, int, int) override {}
344 void generate_CallName(int, int, int) override {}
345 void generate_CallPossiblyDirectEval(int, int) override {}
346 void generate_CallProperty(int, int, int, int) override {}
347 void generate_CallPropertyLookup(int, int, int, int) override {}
348 void generate_CallQmlContextPropertyLookup(int, int, int) override {}
349 void generate_CallValue(int, int, int) override {}
350 void generate_CallWithReceiver(int, int, int, int) override {}
351 void generate_CallWithSpread(int, int, int, int) override {}
352 void generate_CheckException() override {}
353 void generate_CloneBlockContext() override {}
354 void generate_CmpEq(int) override {}
355 void generate_CmpEqInt(int) override {}
356 void generate_CmpEqNull() override {}
357 void generate_CmpGe(int) override {}
358 void generate_CmpGt(int) override {}
359 void generate_CmpIn(int) override {}
360 void generate_CmpInstanceOf(int) override {}
361 void generate_CmpLe(int) override {}
362 void generate_CmpLt(int) override {}
363 void generate_CmpNe(int) override {}
364 void generate_CmpNeInt(int) override {}
365 void generate_CmpNeNull() override {}
366 void generate_CmpStrictEqual(int) override {}
367 void generate_CmpStrictNotEqual(int) override {}
368 void generate_Construct(int, int, int) override {}
369 void generate_ConstructWithSpread(int, int, int) override {}
371 void generate_CreateCallContext() override {}
372 void generate_CreateClass(int, int, int) override {}
374 void generate_CreateRestParameter(int) override {}
376 void generate_DeadTemporalZoneCheck(int) override {}
377 void generate_Debug() override {}
378 void generate_DeclareVar(int, int) override {}
379 void generate_Decrement() override {}
380 void generate_DefineArray(int, int) override {}
381 void generate_DefineObjectLiteral(int, int, int) override {}
382 void generate_DeleteName(int) override {}
383 void generate_DeleteProperty(int, int) override {}
385 void generate_Div(int) override {}
386 void generate_Exp(int) override {}
387 void generate_GetException() override {}
388 void generate_GetIterator(int) override {}
389 void generate_GetLookup(int) override {}
390 void generate_GetOptionalLookup(int, int) override {}
391 void generate_GetTemplateObject(int) override {}
392 void generate_Increment() override {}
394 void generate_IteratorClose(int) override {}
395 void generate_IteratorNext(int, int) override {}
396 void generate_IteratorNextForYieldStar(int, int) override {}
397 void generate_Jump(int) override {}
398 void generate_JumpFalse(int) override {}
399 void generate_JumpNoException(int) override {}
400 void generate_JumpNotUndefined(int) override {}
401 void generate_JumpTrue(int) override {}
402 void generate_LoadClosure(int) override {}
403 void generate_LoadConst(int) override {}
404 void generate_LoadElement(int) override {}
405 void generate_LoadFalse() override {}
406 void generate_LoadGlobalLookup(int) override {}
407 void generate_LoadImport(int) override {}
408 void generate_LoadInt(int) override {}
409 void generate_LoadLocal(int) override {}
410 void generate_LoadName(int) override {}
411 void generate_LoadNull() override {}
412 void generate_LoadOptionalProperty(int, int) override {}
413 void generate_LoadProperty(int) override {}
415 void generate_LoadReg(int) override {}
416 void generate_LoadRuntimeString(int) override {}
417 void generate_LoadScopedLocal(int, int) override {}
419 void generate_LoadSuperProperty(int) override {}
420 void generate_LoadTrue() override {}
421 void generate_LoadUndefined() override {}
422 void generate_LoadZero() override {}
423 void generate_Mod(int) override {}
424 void generate_MoveConst(int, int) override {}
425 void generate_MoveReg(int, int) override {}
426 void generate_MoveRegExp(int, int) override {}
427 void generate_Mul(int) override {}
428 void generate_PopContext() override {}
429 void generate_PopScriptContext() override {}
430 void generate_PushBlockContext(int) override {}
431 void generate_PushCatchContext(int, int) override {}
432 void generate_PushScriptContext(int) override {}
433 void generate_PushWithContext() override {}
434 void generate_Resume(int) override {}
435 void generate_Ret() override {}
436 void generate_SetException() override {}
437 void generate_SetLookup(int, int) override {}
438 void generate_SetUnwindHandler(int) override {}
439 void generate_Shl(int) override {}
440 void generate_ShlConst(int) override {}
441 void generate_Shr(int) override {}
442 void generate_ShrConst(int) override {}
443 void generate_StoreElement(int, int) override {}
444 void generate_StoreLocal(int) override {}
445 void generate_StoreNameSloppy(int) override {}
446 void generate_StoreNameStrict(int) override {}
447 void generate_StoreProperty(int, int) override {}
448 void generate_StoreReg(int) override {}
449 void generate_StoreScopedLocal(int, int) override {}
450 void generate_StoreSuperProperty(int) override {}
451 void generate_Sub(int) override {}
452 void generate_TailCall(int, int, int, int) override {}
453 void generate_ThrowException() override {}
455 void generate_ToObject() override {}
456 void generate_TypeofName(int) override {}
457 void generate_TypeofValue() override {}
458 void generate_UCompl() override {}
459 void generate_UMinus() override {}
460 void generate_UNot() override {}
461 void generate_UPlus() override {}
462 void generate_UShr(int) override {}
463 void generate_UShrConst(int) override {}
464 void generate_UnwindDispatch() override {}
465 void generate_UnwindToLabel(int, int) override {}
466 void generate_Yield() override {}
467 void generate_YieldStar() override {}
468};
469
471
472#endif // QQMLJSCOMPILEPASS_P_H
\inmodule QtCore
Definition qbytearray.h:57
iterator begin()
Definition qflatmap_p.h:769
iterator end()
Definition qflatmap_p.h:773
bool contains(const Key &key) const
Definition qflatmap_p.h:625
iterator find(const Key &key)
Definition qflatmap_p.h:816
const_iterator constEnd() const
Definition qflatmap_p.h:776
size_type size() const noexcept
Definition qflatmap_p.h:577
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
void generate_YieldStar() override
void generate_CallValue(int, int, int) override
void generate_LoadRuntimeString(int) override
void generate_GetOptionalLookup(int, int) override
void generate_LoadImport(int) override
void generate_IteratorNextForYieldStar(int, int) override
void generate_LoadName(int) override
void generate_Yield() override
void generate_DeleteName(int) override
void generate_DeleteProperty(int, int) override
void generate_CreateUnmappedArgumentsObject() override
void generate_IteratorClose(int) override
QQmlJSCompilePass(const QV4::Compiler::JSUnitGenerator *jsUnitGenerator, const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger)
const QV4::Compiler::JSUnitGenerator * m_jsUnitGenerator
void generate_CmpEqNull() override
bool isArgument(int registerIndex) const
void generate_BitAndConst(int) override
void generate_CmpEq(int) override
void generate_UnwindToLabel(int, int) override
static bool instructionManipulatesContext(QV4::Moth::Instr::Type type)
void generate_MoveRegExp(int, int) override
void generate_PopScriptContext() override
QQmlJS::SourceLocation sourceLocation(int instructionOffset) const
void generate_UCompl() override
void generate_LoadFalse() override
void generate_CallGlobalLookup(int, int, int) override
void generate_UShrConst(int) override
void generate_CmpStrictNotEqual(int) override
void generate_CallPossiblyDirectEval(int, int) override
void generate_CmpLt(int) override
void generate_LoadQmlContextPropertyLookup(int) override
const Function * m_function
void generate_CloneBlockContext() override
void generate_UNot() override
void generate_Shl(int) override
void generate_LoadZero() override
void generate_Increment() override
void generate_CheckException() override
const QQmlJSTypeResolver * m_typeResolver
QQmlJS::DiagnosticMessage * m_error
void generate_SetUnwindHandler(int) override
void generate_InitializeBlockDeadTemporalZone(int, int) override
void generate_CreateClass(int, int, int) override
void generate_LoadClosure(int) override
void generate_TypeofValue() override
void generate_ConstructWithSpread(int, int, int) override
void generate_JumpTrue(int) override
void generate_StoreProperty(int, int) override
void generate_JumpFalse(int) override
void setError(const QString &message)
void generate_IteratorNext(int, int) override
void generate_UnwindDispatch() override
void generate_As(int) override
void generate_SetLookup(int, int) override
void generate_LoadTrue() override
void generate_ShlConst(int) override
void generate_CallWithSpread(int, int, int, int) override
void generate_LoadProperty(int) override
void generate_BitXor(int) override
void generate_StoreReg(int) override
void generate_LoadUndefined() override
State initialState(const Function *function)
void generate_Sub(int) override
void generate_LoadScopedLocal(int, int) override
void generate_StoreNameStrict(int) override
void generate_CreateCallContext() override
void generate_CmpGe(int) override
void generate_LoadConst(int) override
void generate_ToObject() override
void generate_SetException() override
void generate_CmpLe(int) override
void generate_Resume(int) override
void generate_StoreNameSloppy(int) override
void generate_Construct(int, int, int) override
void generate_Jump(int) override
void generate_CreateRestParameter(int) override
void generate_LoadReg(int) override
void generate_LoadGlobalLookup(int) override
void generate_StoreElement(int, int) override
void generate_Add(int) override
void generate_UMinus() override
void generate_CallName(int, int, int) override
void generate_Decrement() override
void generate_PushScriptContext(int) override
void generate_GetException() override
void generate_PushBlockContext(int) override
void generate_LoadInt(int) override
void generate_LoadElement(int) override
void generate_CallQmlContextPropertyLookup(int, int, int) override
void generate_Shr(int) override
void generate_PushWithContext() override
void generate_TypeofName(int) override
void generate_CallWithReceiver(int, int, int, int) override
void generate_BitXorConst(int) override
State nextStateFromAnnotations(const State &oldState, const InstructionAnnotations &annotations)
void generate_LoadLocal(int) override
void generate_CmpNeInt(int) override
QQmlJS::SourceLocation currentSourceLocation() const
void generate_MoveReg(int, int) override
void generate_Debug() override
void generate_StoreLocal(int) override
void generate_CmpNe(int) override
void generate_GetIterator(int) override
void generate_CmpGt(int) override
void generate_UPlus() override
void generate_CmpNeNull() override
void generate_DestructureRestElement() override
void generate_GetTemplateObject(int) override
void generate_CallProperty(int, int, int, int) override
void generate_StoreSuperProperty(int) override
void generate_BitOrConst(int) override
void generate_Exp(int) override
void generate_UShr(int) override
void generate_ShrConst(int) override
void generate_StoreScopedLocal(int, int) override
void generate_GetLookup(int) override
void generate_DefineArray(int, int) override
void generate_LoadSuperProperty(int) override
void generate_JumpNotUndefined(int) override
void generate_CmpStrictEqual(int) override
void generate_CreateMappedArgumentsObject() override
void generate_BitOr(int) override
void generate_Ret() override
void generate_PushCatchContext(int, int) override
void generate_MoveConst(int, int) override
void generate_ThrowException() override
void generate_TailCall(int, int, int, int) override
void generate_DeadTemporalZoneCheck(int) override
void generate_ThrowOnNullOrUndefined() override
void generate_JumpNoException(int) override
void generate_PopContext() override
void generate_LoadNull() override
void generate_BitAnd(int) override
void generate_ConvertThisToObject() override
void generate_Mod(int) override
void generate_CmpIn(int) override
void generate_CmpInstanceOf(int) override
void setError(const QString &message, int instructionOffset)
void generate_CmpEqInt(int) override
void generate_Mul(int) override
void generate_DefineObjectLiteral(int, int, int) override
QQmlJSRegisterContent argumentType(int registerIndex) const
void generate_CallPropertyLookup(int, int, int, int) override
void generate_DeclareVar(int, int) override
void generate_Div(int) override
void generate_LoadOptionalProperty(int, int) override
void generate_LoadSuperConstructor() override
iterator begin()
Definition qset.h:136
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QSet< QString >::iterator it
else opt state
[0]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLenum type
GLenum target
GLuint GLsizei const GLchar * message
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
GLuint entry
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int uint
Definition qtypes.h:29
QGraphicsItem * item
QList< QQmlJSRegisterContent > argumentTypes
QQmlJSScope::ConstPtr qmlScope
const SourceLocationTable * sourceLocations
QQmlJSScope::ConstPtr returnType
QList< QQmlJSRegisterContent > registerTypes
const QQmlJSRegisterContent & accumulatorIn() const
void addReadAccumulator(const QQmlJSRegisterContent &reg)
VirtualRegisters takeReadRegisters() const
bool canMoveReadRegister(int registerIndex) const
bool isRegisterAffectedBySideEffects(int registerIndex) const
void setReadRegisters(VirtualRegisters readReagisters)
bool readsRegister(int registerIndex) const
QQmlJSRegisterContent readRegister(int registerIndex) const
const QQmlJSRegisterContent & changedRegister() const
void setIsRename(bool isRename)
void setRegister(int registerIndex, QQmlJSRegisterContent content)
void addReadRegister(int registerIndex, const QQmlJSRegisterContent &reg)
void setHasSideEffects(bool hasSideEffects)
QQmlJSRegisterContent readAccumulator() const
const QQmlJSRegisterContent & accumulatorOut() const
friend bool operator==(const VirtualRegister &a, const VirtualRegister &b)
Definition moc.h:24