Merge master <-> api_changes
[profile/ivi/qtdeclarative.git] / src / qml / qml / v4 / qv4compiler_p_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QV4COMPILER_P_P_H
43 #define QV4COMPILER_P_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
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.
52 //
53 // We mean it.
54 //
55
56 #include "qv4instruction_p.h"
57 #include "qv4ir_p.h"
58 #include <private/qqmlscript_p.h>
59 #include <private/qqmlimport_p.h>
60 #include <private/qqmlengine_p.h>
61
62 QT_BEGIN_HEADER
63
64 QT_BEGIN_NAMESPACE
65
66 template <typename _Key, typename _Value>
67 class QQmlAssociationList
68 {
69 public:
70     typedef QVarLengthArray<QPair<_Key, _Value>, 8> Container;
71     typedef typename Container::const_iterator const_iterator;
72     typedef typename Container::const_iterator ConstIterator;
73
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(); }
78
79     _Value *value(const _Key &key) {
80         for (int i = 0; i < _container.size(); ++i) {
81             QPair<_Key, _Value> &p = _container[i];
82             if (p.first == key)
83                 return &p.second;
84         }
85         return 0;
86     }
87
88     _Value &operator[](const _Key &key) {
89         for (int i = 0; i < _container.size(); ++i) {
90             QPair<_Key, _Value> &p = _container[i];
91             if (p.first == key)
92                 return p.second;
93         }
94         int index = _container.size();
95         _container.append(qMakePair(key, _Value()));
96         return _container[index].second;
97     }
98
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) {
103                 p.second = value;
104                 return;
105             }
106         }
107         _container.append(qMakePair(key, value));
108     }
109
110 private:
111     Container _container;
112 };
113
114 class QV4CompilerPrivate: protected QQmlJS::IR::ExprVisitor, 
115                                      protected QQmlJS::IR::StmtVisitor
116 {
117 public:
118     QV4CompilerPrivate();
119
120     void resetInstanceState();
121     int commitCompile();
122
123     const QV4Compiler::Expression *expression;
124     QQmlEnginePrivate *engine;
125
126     QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)expression->context, 16); }
127
128     bool compile(QQmlJS::AST::Node *);
129
130     int registerLiteralString(quint8 reg, const QStringRef &);
131     int registerString(const QString &);
132     QQmlAssociationList<QString, QPair<int, int> > registeredStrings;
133     QByteArray data;
134
135     bool blockNeedsSubscription(const QStringList &);
136     int subscriptionIndex(const QStringList &);
137     quint32 subscriptionBlockMask(const QStringList &);
138
139     quint8 exceptionId(quint32 line, quint32 column);
140     quint8 exceptionId(QQmlJS::AST::ExpressionNode *);
141     QVector<quint64> exceptions;
142
143     QQmlAssociationList<int, quint32> usedSubscriptionIds;
144
145     QQmlAssociationList<QString, int> subscriptionIds;
146     QQmlJS::Bytecode bytecode;
147
148     // back patching
149     struct Patch {
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) {}
154     };
155     QVector<Patch> patches;
156     QQmlPool pool;
157
158     // Committed binding data
159     struct {
160         QList<int> offsets;
161         QList<QQmlAssociationList<int, quint32> > dependencies;
162
163         //QQmlJS::Bytecode bytecode;
164         QByteArray bytecode;
165         QByteArray data;
166         QQmlAssociationList<QString, int> subscriptionIds;
167         QVector<quint64> exceptions;
168
169         QQmlAssociationList<QString, QPair<int, int> > registeredStrings;
170
171         int count() const { return offsets.count(); }
172     } committed;
173
174     QByteArray buildSignalTable() const;
175     QByteArray buildExceptionData() const;
176
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);
181
182     struct Instr {
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
186     private:
187         Instr();
188     };
189
190 protected:
191     //
192     // tracing
193     //
194     void trace(int line, int column);
195     void trace(QVector<QQmlJS::IR::BasicBlock *> *blocks);
196     void traceExpression(QQmlJS::IR::Expr *e, quint8 r);
197
198     template <int Instr>
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); }
203
204     inline QQmlJS::V4Instr::Type instructionType(const QQmlJS::V4Instr *i) const
205     { return bytecode.instructionType(i); }
206
207     //
208     // expressions
209     //
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);
217
218     //
219     // statements
220     //
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);
226
227 private:
228     QStringList _subscribeName;
229     QQmlJS::IR::Function *_function;
230     QQmlJS::IR::BasicBlock *_block;
231     void discard() { _discarded = true; }
232     bool _discarded;
233     quint8 currentReg;
234     quint8 registerCount;
235
236     bool usedSubscriptionIdsChanged;
237     quint32 currentBlockMask;
238 };
239
240
241 QT_END_NAMESPACE
242
243 QT_END_HEADER
244
245 #endif // QV4COMPILER_P_P_H
246