7115f514284ed00e3c474cd3501dca064dff75a5
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v4 / qv4compiler_p_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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/qdeclarativescript_p.h>
59 #include <private/qdeclarativeimport_p.h>
60 #include <private/qdeclarativeengine_p.h>
61
62 QT_BEGIN_HEADER
63
64 QT_BEGIN_NAMESPACE
65
66 // NOTE: This is a copy of QDeclarative1AnchorLine: src/qtquick1/graphicsitems/qdeclarativeanchors_p_p.h
67 class QGraphicsObject;
68 class QDeclarative1AnchorLine
69 {
70 public:
71     QDeclarative1AnchorLine() : item(0), anchorLine(Invalid) {}
72
73     enum AnchorLine {
74         Invalid = 0x0,
75         Left = 0x01,
76         Right = 0x02,
77         Top = 0x04,
78         Bottom = 0x08,
79         HCenter = 0x10,
80         VCenter = 0x20,
81         Baseline = 0x40,
82         Horizontal_Mask = Left | Right | HCenter,
83         Vertical_Mask = Top | Bottom | VCenter | Baseline
84     };
85
86     QGraphicsObject *item;
87     AnchorLine anchorLine;
88 };
89
90 inline bool operator==(const QDeclarative1AnchorLine& a, const QDeclarative1AnchorLine& b)
91 {
92     return a.item == b.item && a.anchorLine == b.anchorLine;
93 }
94
95
96 template <typename _Key, typename _Value>
97 class QDeclarativeAssociationList
98 {
99 public:
100     typedef QVarLengthArray<QPair<_Key, _Value>, 8> Container;
101     typedef typename Container::const_iterator const_iterator;
102     typedef typename Container::const_iterator ConstIterator;
103
104     const_iterator begin() const { return _container.begin(); }
105     const_iterator end() const { return _container.end(); }
106     int count() const { return _container.count(); }
107     void clear() { _container.clear(); }
108
109     _Value *value(const _Key &key) {
110         for (int i = 0; i < _container.size(); ++i) {
111             QPair<_Key, _Value> &p = _container[i];
112             if (p.first == key)
113                 return &p.second;
114         }
115         return 0;
116     }
117
118     _Value &operator[](const _Key &key) {
119         for (int i = 0; i < _container.size(); ++i) {
120             QPair<_Key, _Value> &p = _container[i];
121             if (p.first == key)
122                 return p.second;
123         }
124         int index = _container.size();
125         _container.append(qMakePair(key, _Value()));
126         return _container[index].second;
127     }
128
129     void insert(const _Key &key, _Value &value) {
130         for (int i = 0; i < _container.size(); ++i) {
131             QPair<_Key, _Value> &p = _container[i];
132             if (p.first == key) {
133                 p.second = value;
134                 return;
135             }
136         }
137         _container.append(qMakePair(key, value));
138     }
139
140 private:
141     Container _container;
142 };
143
144 class QV4CompilerPrivate: protected QDeclarativeJS::IR::ExprVisitor, 
145                                      protected QDeclarativeJS::IR::StmtVisitor
146 {
147 public:
148     QV4CompilerPrivate();
149
150     void resetInstanceState();
151     int commitCompile();
152
153     const QV4Compiler::Expression *expression;
154     QDeclarativeEnginePrivate *engine;
155
156     QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)expression->context, 16); }
157
158     bool compile(QDeclarativeJS::AST::Node *);
159
160     int registerLiteralString(quint8 reg, const QStringRef &);
161     int registerString(const QString &);
162     QDeclarativeAssociationList<QString, QPair<int, int> > registeredStrings;
163     QByteArray data;
164
165     bool blockNeedsSubscription(const QStringList &);
166     int subscriptionIndex(const QStringList &);
167     quint32 subscriptionBlockMask(const QStringList &);
168
169     quint8 exceptionId(quint32 line, quint32 column);
170     quint8 exceptionId(QDeclarativeJS::AST::ExpressionNode *);
171     QVector<quint64> exceptions;
172
173     QDeclarativeAssociationList<int, quint32> usedSubscriptionIds;
174
175     QDeclarativeAssociationList<QString, int> subscriptionIds;
176     QDeclarativeJS::Bytecode bytecode;
177
178     // back patching
179     struct Patch {
180         QDeclarativeJS::IR::BasicBlock *block; // the basic block
181         int offset; // the index of the instruction to patch
182         Patch(QDeclarativeJS::IR::BasicBlock *block = 0, int index = -1)
183             : block(block), offset(index) {}
184     };
185     QVector<Patch> patches;
186     QDeclarativePool pool;
187
188     // Committed binding data
189     struct {
190         QList<int> offsets;
191         QList<QDeclarativeAssociationList<int, quint32> > dependencies;
192
193         //QDeclarativeJS::Bytecode bytecode;
194         QByteArray bytecode;
195         QByteArray data;
196         QDeclarativeAssociationList<QString, int> subscriptionIds;
197         QVector<quint64> exceptions;
198
199         QDeclarativeAssociationList<QString, QPair<int, int> > registeredStrings;
200
201         int count() const { return offsets.count(); }
202     } committed;
203
204     QByteArray buildSignalTable() const;
205     QByteArray buildExceptionData() const;
206
207     void convertToReal(QDeclarativeJS::IR::Expr *expr, int reg);    
208     void convertToInt(QDeclarativeJS::IR::Expr *expr, int reg);
209     void convertToBool(QDeclarativeJS::IR::Expr *expr, int reg);
210     quint8 instructionOpcode(QDeclarativeJS::IR::Binop *e);
211
212     struct Instr {
213 #define QML_V4_INSTR_DATA_TYPEDEF(I, FMT) typedef QDeclarativeJS::V4InstrData<QDeclarativeJS::V4Instr::I> I;
214     FOR_EACH_V4_INSTR(QML_V4_INSTR_DATA_TYPEDEF)
215 #undef QML_v4_INSTR_DATA_TYPEDEF
216     private:
217         Instr();
218     };
219
220 protected:
221     //
222     // tracing
223     //
224     void trace(int line, int column);
225     void trace(QVector<QDeclarativeJS::IR::BasicBlock *> *blocks);
226     void traceExpression(QDeclarativeJS::IR::Expr *e, quint8 r);
227
228     template <int Instr>
229     inline void gen(const QDeclarativeJS::V4InstrData<Instr> &i)
230     { bytecode.append(i); }
231     inline void gen(QDeclarativeJS::V4Instr::Type type, QDeclarativeJS::V4Instr &instr)
232     { bytecode.append(type, instr); }
233
234     inline QDeclarativeJS::V4Instr::Type instructionType(const QDeclarativeJS::V4Instr *i) const
235     { return bytecode.instructionType(i); }
236
237     //
238     // expressions
239     //
240     virtual void visitConst(QDeclarativeJS::IR::Const *e);
241     virtual void visitString(QDeclarativeJS::IR::String *e);
242     virtual void visitName(QDeclarativeJS::IR::Name *e);
243     virtual void visitTemp(QDeclarativeJS::IR::Temp *e);
244     virtual void visitUnop(QDeclarativeJS::IR::Unop *e);
245     virtual void visitBinop(QDeclarativeJS::IR::Binop *e);
246     virtual void visitCall(QDeclarativeJS::IR::Call *e);
247
248     //
249     // statements
250     //
251     virtual void visitExp(QDeclarativeJS::IR::Exp *s);
252     virtual void visitMove(QDeclarativeJS::IR::Move *s);
253     virtual void visitJump(QDeclarativeJS::IR::Jump *s);
254     virtual void visitCJump(QDeclarativeJS::IR::CJump *s);
255     virtual void visitRet(QDeclarativeJS::IR::Ret *s);
256
257 private:
258     QStringList _subscribeName;
259     QDeclarativeJS::IR::Function *_function;
260     QDeclarativeJS::IR::BasicBlock *_block;
261     void discard() { _discarded = true; }
262     bool _discarded;
263     quint8 currentReg;
264
265     bool usedSubscriptionIdsChanged;
266     quint32 currentBlockMask;
267 };
268
269
270 QT_END_NAMESPACE
271
272 Q_DECLARE_METATYPE(QDeclarative1AnchorLine)
273
274 QT_END_HEADER
275
276 #endif // QV4COMPILER_P_P_H
277