1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QV4COMPILER_P_P_H
43 #define QV4COMPILER_P_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
56 #include "qv4instruction_p.h"
58 #include <private/qqmlscript_p.h>
59 #include <private/qqmlimport_p.h>
60 #include <private/qqmlengine_p.h>
66 template <typename _Key, typename _Value>
67 class QQmlAssociationList
70 typedef QVarLengthArray<QPair<_Key, _Value>, 8> Container;
71 typedef typename Container::const_iterator const_iterator;
72 typedef typename Container::const_iterator ConstIterator;
74 const_iterator begin() const { return _container.begin(); }
75 const_iterator end() const { return _container.end(); }
76 int count() const { return _container.count(); }
77 void clear() { _container.clear(); }
79 _Value *value(const _Key &key) {
80 for (int i = 0; i < _container.size(); ++i) {
81 QPair<_Key, _Value> &p = _container[i];
88 _Value &operator[](const _Key &key) {
89 for (int i = 0; i < _container.size(); ++i) {
90 QPair<_Key, _Value> &p = _container[i];
94 int index = _container.size();
95 _container.append(qMakePair(key, _Value()));
96 return _container[index].second;
99 void insert(const _Key &key, _Value &value) {
100 for (int i = 0; i < _container.size(); ++i) {
101 QPair<_Key, _Value> &p = _container[i];
102 if (p.first == key) {
107 _container.append(qMakePair(key, value));
111 Container _container;
114 class QV4CompilerPrivate: protected QQmlJS::IR::ExprVisitor,
115 protected QQmlJS::IR::StmtVisitor
118 QV4CompilerPrivate();
120 void resetInstanceState();
123 const QV4Compiler::Expression *expression;
124 QQmlEnginePrivate *engine;
126 QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)expression->context, 16); }
128 bool compile(QQmlJS::AST::Node *);
130 int registerLiteralString(quint8 reg, const QStringRef &);
131 int registerString(const QString &);
132 QQmlAssociationList<QString, QPair<int, int> > registeredStrings;
135 bool blockNeedsSubscription(const QStringList &);
136 int subscriptionIndex(const QStringList &);
137 quint32 subscriptionBlockMask(const QStringList &);
139 quint8 exceptionId(quint32 line, quint32 column);
140 quint8 exceptionId(QQmlJS::AST::ExpressionNode *);
141 QVector<quint64> exceptions;
143 QQmlAssociationList<int, quint32> usedSubscriptionIds;
145 QQmlAssociationList<QString, int> subscriptionIds;
146 QQmlJS::Bytecode bytecode;
150 QQmlJS::IR::BasicBlock *block; // the basic block
151 int offset; // the index of the instruction to patch
152 Patch(QQmlJS::IR::BasicBlock *block = 0, int index = -1)
153 : block(block), offset(index) {}
155 QVector<Patch> patches;
158 // Committed binding data
161 QList<QQmlAssociationList<int, quint32> > dependencies;
163 //QQmlJS::Bytecode bytecode;
166 QQmlAssociationList<QString, int> subscriptionIds;
167 QVector<quint64> exceptions;
169 QQmlAssociationList<QString, QPair<int, int> > registeredStrings;
171 int count() const { return offsets.count(); }
174 QByteArray buildSignalTable() const;
175 QByteArray buildExceptionData() const;
177 void convertToReal(QQmlJS::IR::Expr *expr, int reg);
178 void convertToInt(QQmlJS::IR::Expr *expr, int reg);
179 void convertToBool(QQmlJS::IR::Expr *expr, int reg);
180 quint8 instructionOpcode(QQmlJS::IR::Binop *e);
183 #define QML_V4_INSTR_DATA_TYPEDEF(I, FMT) typedef QQmlJS::V4InstrData<QQmlJS::V4Instr::I> I;
184 FOR_EACH_V4_INSTR(QML_V4_INSTR_DATA_TYPEDEF)
185 #undef QML_v4_INSTR_DATA_TYPEDEF
194 void trace(int line, int column);
195 void trace(QVector<QQmlJS::IR::BasicBlock *> *blocks);
196 void traceExpression(QQmlJS::IR::Expr *e, quint8 r);
199 inline void gen(const QQmlJS::V4InstrData<Instr> &i)
200 { bytecode.append(i); }
201 inline void gen(QQmlJS::V4Instr::Type type, QQmlJS::V4Instr &instr)
202 { bytecode.append(type, instr); }
204 inline QQmlJS::V4Instr::Type instructionType(const QQmlJS::V4Instr *i) const
205 { return bytecode.instructionType(i); }
210 virtual void visitConst(QQmlJS::IR::Const *e);
211 virtual void visitString(QQmlJS::IR::String *e);
212 virtual void visitName(QQmlJS::IR::Name *e);
213 virtual void visitTemp(QQmlJS::IR::Temp *e);
214 virtual void visitUnop(QQmlJS::IR::Unop *e);
215 virtual void visitBinop(QQmlJS::IR::Binop *e);
216 virtual void visitCall(QQmlJS::IR::Call *e);
221 virtual void visitExp(QQmlJS::IR::Exp *s);
222 virtual void visitMove(QQmlJS::IR::Move *s);
223 virtual void visitJump(QQmlJS::IR::Jump *s);
224 virtual void visitCJump(QQmlJS::IR::CJump *s);
225 virtual void visitRet(QQmlJS::IR::Ret *s);
228 QStringList _subscribeName;
229 QQmlJS::IR::Function *_function;
230 QQmlJS::IR::BasicBlock *_block;
231 void discard() { _discarded = true; }
234 quint8 registerCount;
236 bool usedSubscriptionIdsChanged;
237 quint32 currentBlockMask;
245 #endif // QV4COMPILER_P_P_H