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
qv4compilercontext_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 QV4COMPILERCONTEXT_P_H
6#define QV4COMPILERCONTEXT_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/qqmljsast_p.h>
20#include <private/qv4compileddata_p.h>
21#include <QtCore/QStringList>
22#include <QtCore/QDateTime>
23#include <QtCore/QStack>
24#include <QtCore/QHash>
25#include <QtCore/QMap>
26#include <QtCore/QSet>
27#include <QtCore/QVarLengthArray>
28
29#include <memory>
30
31QT_BEGIN_NAMESPACE
32
33namespace QV4 {
34
35namespace Moth {
37}
38
39namespace Compiler {
40
41class Codegen;
42struct ControlFlow;
43
44enum class ContextType {
48 Binding, // This is almost the same as Eval, except:
49 // * function declarations are moved to the return address when encountered
50 // * return statements are allowed everywhere (like in FunctionCode)
51 // * variable declarations are treated as true locals (like in FunctionCode)
55};
56
57struct Context;
58
76
80 bool operator==(const TemplateObject &other) {
81 return strings == other.strings && rawStrings == other.rawStrings;
82 }
83};
84
86{
92
93 static bool lessThan(const ExportEntry &lhs, const ExportEntry &rhs)
94 { return lhs.exportName < rhs.exportName; }
95};
96
104
105struct Module {
106 Module(const QString &fileName, const QString &finalUrl, bool debugMode)
109 , debugMode(debugMode)
110 {}
112 qDeleteAll(contextMap);
113 }
114
115 Context *newContext(QQmlJS::AST::Node *node, Context *parent, ContextType compilationMode);
116
126 uint unitFlags = 0; // flags merged into CompiledData::Unit::flags
127 bool debugMode = false;
133};
134
135
136struct Context {
139 int line = 0;
140 int column = 0;
143 int blockIndex = -1;
144
152
162
163 struct Member {
165 int index = -1;
167 mutable bool canEscape = false;
168 bool isInjected = false;
172
173 bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableScope::Var; }
174 bool requiresTDZCheck(const QQmlJS::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const;
175 };
177
182 QQmlJS::AST::Type *returnType = nullptr;
189
194 std::vector<unsigned> labelInfo;
195
196 int nRegisters = 0;
201 bool hasDirectEval = false;
202 bool allVarsEscape = false;
203 bool hasNestedFunctions = false;
204 bool isStrict = false;
205 bool isArrowFunction = false;
206 bool isGenerator = false;
207 bool usesThis = false;
210 bool returnsClosure = false;
211 mutable bool argumentsCanEscape = false;
213 bool isWithBlock = false;
214 bool isCatchBlock = false;
217
223
225
227
228 template <typename T>
229 class SmallSet: public QVarLengthArray<T, 8>
230 {
231 public:
232 void insert(int value)
233 {
234 for (auto it : *this) {
235 if (it == value)
236 return;
237 }
238 this->append(value);
239 }
240 };
241
242 // Map from meta property index (existence implies dependency) to notify signal index
244 {
247
249 KeyValuePair(quint32 key, quint32 value): _key(key), _value(value) {}
250
251 quint32 key() const { return _key; }
252 quint32 value() const { return _value; }
253 };
254
256 {
257 public:
258 void insert(quint32 key, quint32 value)
259 {
260 for (auto it = begin(), eit = end(); it != eit; ++it) {
261 if (it->_key == key) {
262 it->_value = value;
263 return;
264 }
265 }
266 append(KeyValuePair(key, value));
267 }
268 };
269
271 : parent(parent)
272 , contextType(type)
273 {
274 if (parent && parent->isStrict)
275 isStrict = true;
276 }
277
278 bool hasArgument(const QString &name) const
279 {
280 return arguments.contains(name);
281 }
282
283 int findArgument(const QString &name, bool *isInjected) const
284 {
285 // search backwards to handle duplicate argument names correctly
286 for (int i = arguments.size() - 1; i >= 0; --i) {
287 const auto &arg = arguments.at(i);
288 if (arg.id == name) {
289 *isInjected = arg.isInjected();
290 return i;
291 }
292 }
293 return -1;
294 }
295
296 Member findMember(const QString &name) const
297 {
298 MemberMap::const_iterator it = members.find(name);
299 if (it == members.end())
300 return Member();
301 Q_ASSERT(it->index != -1 || !parent);
302 return (*it);
303 }
304
305 bool memberInfo(const QString &name, const Member **m) const
306 {
307 Q_ASSERT(m);
308 MemberMap::const_iterator it = members.find(name);
309 if (it == members.end()) {
310 *m = nullptr;
311 return false;
312 }
313 *m = &(*it);
314 return true;
315 }
316
322
323 void addUsedVariable(const QString &name) {
324 usedVariables.insert(name);
325 }
326
327 bool addLocalVar(
328 const QString &name, MemberType contextType, QQmlJS::AST::VariableScope scope,
329 QQmlJS::AST::FunctionExpression *function = nullptr,
330 const QQmlJS::SourceLocation &declarationLocation = QQmlJS::SourceLocation(),
331 bool isInjected = false);
332
333 void promoteFormalParameterForTDZ(const QString &name, const QQmlJS::SourceLocation &loc);
334
355 ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation);
356 void emitBlockHeader(Compiler::Codegen *codegen);
357 void emitBlockFooter(Compiler::Codegen *codegen);
358
359 void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator);
360
361 bool canHaveTailCalls() const
362 {
363 if (!isStrict)
364 return false;
366 return !isGenerator;
369 return false;
370 }
371
372 bool isCaseBlock() const
373 {
374 return contextType == ContextType::Block && name == u"%CaseBlock";
375 }
376};
377
378
379} } // namespace QV4::Compiler
380
381QT_END_NAMESPACE
382
383#endif // QV4CODEGEN_P_H
Definition qjsvalue.h:24
QList< Method > staticMethods
KeyValuePair(quint32 key, quint32 value)
QQmlJS::AST::FunctionExpression * function
bool requiresTDZCheck(const QQmlJS::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const
QQmlJS::SourceLocation declarationLocation
QQmlJS::AST::VariableScope scope
QList< Context * > nestedContexts
bool memberInfo(const QString &name, const Member **m) const
void emitBlockFooter(Compiler::Codegen *codegen)
QQmlJS::AST::FormalParameterList * formals
bool hasArgument(const QString &name) const
void emitBlockHeader(Compiler::Codegen *codegen)
QQmlJS::AST::BoundNames arguments
std::unique_ptr< SourceLocationTable > sourceLocationTable
UsesArgumentsObject usesArgumentsObject
QList< CompiledData::CodeOffsetToLineAndStatement > lineAndStatementNumberMapping
QList< ImportEntry > importEntries
QMap< QString, Member > MemberMap
QQmlJS::AST::Type * returnType
Context(Context *parent, ContextType type)
ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation)
void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
QQmlJS::SourceLocation lastBlockInitializerLocation
void addUsedVariable(const QString &name)
void promoteFormalParameterForTDZ(const QString &name, const QQmlJS::SourceLocation &loc)
QList< ExportEntry > exportEntries
std::vector< unsigned > labelInfo
Member findMember(const QString &name) const
bool addLocalVar(const QString &name, MemberType contextType, QQmlJS::AST::VariableScope scope, QQmlJS::AST::FunctionExpression *function=nullptr, const QQmlJS::SourceLocation &declarationLocation=QQmlJS::SourceLocation(), bool isInjected=false)
int findArgument(const QString &name, bool *isInjected) const
CompiledData::Location location
static bool lessThan(const ExportEntry &lhs, const ExportEntry &rhs)
CompiledData::Location location
Context * newContext(QQmlJS::AST::Node *node, Context *parent, ContextType compilationMode)
QHash< QQmlJS::AST::Node *, Context * > contextMap
QList< ExportEntry > indirectExportEntries
QList< Context * > functions
Module(const QString &fileName, const QString &finalUrl, bool debugMode)
QList< ExportEntry > starExportEntries
QList< TemplateObject > templateObjects
QList< ImportEntry > importEntries
QList< ExportEntry > localExportEntries
bool operator==(const TemplateObject &other)