Support variable length instructions in QML bytecode
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecompiler_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVECOMPILER_P_H
43 #define QDECLARATIVECOMPILER_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 "qdeclarative.h"
57 #include "qdeclarativeerror.h"
58 #include "private/qdeclarativeinstruction_p.h"
59 #include "private/qdeclarativeparser_p.h"
60 #include "private/qdeclarativeengine_p.h"
61 #include "private/qbitfield_p.h"
62 #include "private/qdeclarativepropertycache_p.h"
63 #include "private/qdeclarativeintegercache_p.h"
64 #include "private/qdeclarativetypenamecache_p.h"
65 #include "private/qdeclarativetypeloader_p.h"
66
67 #include <QtCore/qbytearray.h>
68 #include <QtCore/qset.h>
69 #include <QtCore/QCoreApplication>
70
71 QT_BEGIN_NAMESPACE
72
73 class QDeclarativeEngine;
74 class QDeclarativeComponent;
75 class QDeclarativeContext;
76 class QDeclarativeContextData;
77
78 class QScriptProgram;
79 class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup
80 {
81 public:
82     QDeclarativeCompiledData(QDeclarativeEngine *engine);
83     virtual ~QDeclarativeCompiledData();
84
85     QString name;
86     QUrl url;
87     QDeclarativeTypeNameCache *importCache;
88
89     struct TypeReference 
90     {
91         TypeReference()
92         : type(0), typePropertyCache(0), component(0) {}
93
94         QByteArray className;
95         QDeclarativeType *type;
96         QDeclarativePropertyCache *typePropertyCache;
97         QDeclarativeCompiledData *component;
98
99         QObject *createInstance(QDeclarativeContextData *, const QBitField &, QList<QDeclarativeError> *) const;
100         const QMetaObject *metaObject() const;
101         QDeclarativePropertyCache *propertyCache() const;
102         QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
103     };
104     QList<TypeReference> types;
105     struct CustomTypeData
106     {
107         int index;
108         int type;
109     };
110
111     const QMetaObject *root;
112     QAbstractDynamicMetaObject rootData;
113     QDeclarativePropertyCache *rootPropertyCache;
114     QList<QString> primitives;
115     QList<float> floatData;
116     QList<int> intData;
117     QList<CustomTypeData> customTypeData;
118     QList<QByteArray> datas;
119     QList<QDeclarativeParser::Location> locations;
120     QByteArray bytecode;
121     QList<QScriptProgram *> cachedPrograms;
122     QList<QScriptValue *> cachedClosures;
123     QList<QDeclarativePropertyCache *> propertyCaches;
124     QList<QDeclarativeIntegerCache *> contextCaches;
125     QList<QDeclarativeScriptData *> scripts;
126     QList<QUrl> urls;
127
128     void dumpInstructions();
129
130     int addInstruction(const QDeclarativeInstruction &instr);
131     int nextInstructionIndex();
132     QDeclarativeInstruction *instruction(int index);
133
134 protected:
135     virtual void clear(); // From QDeclarativeCleanup
136
137 private:
138     void dump(QDeclarativeInstruction *, int idx = -1);
139     QDeclarativeCompiledData(const QDeclarativeCompiledData &other);
140     QDeclarativeCompiledData &operator=(const QDeclarativeCompiledData &other);
141     QByteArray packData;
142     friend class QDeclarativeCompiler;
143     int pack(const char *, size_t);
144
145     int indexForString(const QString &);
146     int indexForByteArray(const QByteArray &);
147     int indexForFloat(float *, int);
148     int indexForInt(int *, int);
149     int indexForLocation(const QDeclarativeParser::Location &);
150     int indexForLocation(const QDeclarativeParser::LocationSpan &);
151     int indexForUrl(const QUrl &);
152 };
153
154 class QMetaObjectBuilder;
155 class Q_AUTOTEST_EXPORT QDeclarativeCompiler
156 {
157     Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
158 public:
159     QDeclarativeCompiler();
160
161     bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
162
163     bool isError() const;
164     QList<QDeclarativeError> errors() const;
165
166     static bool isAttachedPropertyName(const QByteArray &);
167     static bool isSignalPropertyName(const QByteArray &);
168
169     int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
170     const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
171     int rewriteBinding(const QString& expression, const QByteArray& name); // for QDeclarativeCustomParser::rewriteBinding
172
173 private:
174     static void reset(QDeclarativeCompiledData *);
175
176     struct BindingContext {
177         BindingContext()
178             : stack(0), owner(0), object(0) {}
179         BindingContext(QDeclarativeParser::Object *o)
180             : stack(0), owner(0), object(o) {}
181         BindingContext incr() const {
182             BindingContext rv(object);
183             rv.stack = stack + 1;
184             return rv;
185         }
186         bool isSubContext() const { return stack != 0; }
187         int stack;
188         int owner;
189         QDeclarativeParser::Object *object;
190     };
191
192     void compileTree(QDeclarativeParser::Object *tree);
193
194
195     bool buildObject(QDeclarativeParser::Object *obj, const BindingContext &);
196     bool buildComponent(QDeclarativeParser::Object *obj, const BindingContext &);
197     bool buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &);
198     bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, 
199                      const BindingContext &);
200     bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, 
201                        const BindingContext &);
202     bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
203                                   QDeclarativeParser::Property *prop, 
204                                   QDeclarativeParser::Object *obj, 
205                                   const BindingContext &);
206     bool buildIdProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
207     bool buildAttachedProperty(QDeclarativeParser::Property *prop, 
208                                QDeclarativeParser::Object *obj,
209                                const BindingContext &ctxt);
210     bool buildGroupedProperty(QDeclarativeParser::Property *prop,
211                               QDeclarativeParser::Object *obj,
212                               const BindingContext &ctxt);
213     bool buildValueTypeProperty(QObject *type, 
214                                 QDeclarativeParser::Object *obj, 
215                                 QDeclarativeParser::Object *baseObj,
216                                 const BindingContext &ctxt);
217     bool buildListProperty(QDeclarativeParser::Property *prop,
218                            QDeclarativeParser::Object *obj,
219                            const BindingContext &ctxt);
220     bool buildScriptStringProperty(QDeclarativeParser::Property *prop,
221                                    QDeclarativeParser::Object *obj,
222                                    const BindingContext &ctxt);
223     bool buildPropertyAssignment(QDeclarativeParser::Property *prop,
224                                  QDeclarativeParser::Object *obj,
225                                  const BindingContext &ctxt);
226     bool buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
227                                        QDeclarativeParser::Object *obj,
228                                        QDeclarativeParser::Value *value,
229                                        const BindingContext &ctxt);
230     bool buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
231                                    QDeclarativeParser::Object *obj,
232                                    QDeclarativeParser::Object *baseObj,
233                                    QDeclarativeParser::Value *value,
234                                    const BindingContext &ctxt);
235     bool buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
236                                         QDeclarativeParser::Object *obj,
237                                         QDeclarativeParser::Value *value,
238                                         const BindingContext &ctxt);
239     bool doesPropertyExist(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
240     bool testLiteralAssignment(const QMetaProperty &prop, 
241                                QDeclarativeParser::Value *value);
242     bool testQualifiedEnumAssignment(const QMetaProperty &prop,
243                                      QDeclarativeParser::Object *obj,
244                                      QDeclarativeParser::Value *value,
245                                      bool *isAssignment);
246     enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
247     bool mergeDynamicMetaProperties(QDeclarativeParser::Object *obj);
248     bool buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode);
249     bool checkDynamicMeta(QDeclarativeParser::Object *obj);
250     bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop,
251                       const BindingContext &ctxt);
252     bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const BindingContext &);
253     bool compileAlias(QMetaObjectBuilder &, 
254                       QByteArray &data,
255                       QDeclarativeParser::Object *obj, 
256                       const QDeclarativeParser::Object::DynamicProperty &);
257     bool completeComponentBuild();
258     bool checkValidId(QDeclarativeParser::Value *, const QString &);
259
260
261     void genObject(QDeclarativeParser::Object *obj);
262     void genObjectBody(QDeclarativeParser::Object *obj);
263     void genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *);
264     void genComponent(QDeclarativeParser::Object *obj);
265     void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
266     void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
267     void genPropertyAssignment(QDeclarativeParser::Property *prop, 
268                                QDeclarativeParser::Object *obj,
269                                QDeclarativeParser::Property *valueTypeProperty = 0);
270     void genLiteralAssignment(const QMetaProperty &prop, 
271                               QDeclarativeParser::Value *value);
272     void genBindingAssignment(QDeclarativeParser::Value *binding, 
273                               QDeclarativeParser::Property *prop, 
274                               QDeclarativeParser::Object *obj,
275                               QDeclarativeParser::Property *valueTypeProperty = 0);
276     int genContextCache();
277
278     int genValueTypeData(QDeclarativeParser::Property *prop, QDeclarativeParser::Property *valueTypeProp);
279     int genPropertyData(QDeclarativeParser::Property *prop);
280
281     int componentTypeRef();
282
283     static QDeclarativeType *toQmlType(QDeclarativeParser::Object *from);
284     bool canCoerce(int to, QDeclarativeParser::Object *from);
285
286     QStringList deferredProperties(QDeclarativeParser::Object *);
287     int indexOfProperty(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision = 0);
288     int indexOfSignal(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision = 0);
289
290     void addId(const QString &, QDeclarativeParser::Object *);
291
292     void dumpStats();
293
294     struct BindingReference {
295         QDeclarativeParser::Variant expression;
296         QDeclarativeParser::Property *property;
297         QDeclarativeParser::Value *value;
298
299         enum DataType { QtScript, Experimental };
300         DataType dataType;
301
302         int compiledIndex;
303
304         QByteArray compiledData;
305         BindingContext bindingContext;
306     };
307     void addBindingReference(const BindingReference &);
308
309     struct ComponentCompileState
310     {
311         ComponentCompileState() 
312             : parserStatusCount(0), pushedProperties(0), nested(false), root(0) {}
313         QHash<QString, QDeclarativeParser::Object *> ids;
314         QHash<int, QDeclarativeParser::Object *> idIndexes;
315         int parserStatusCount;
316         int pushedProperties;
317         bool nested;
318
319         QByteArray compiledBindingData;
320
321         QHash<QDeclarativeParser::Value *, BindingReference> bindings;
322         QHash<QDeclarativeParser::Value *, BindingContext> signalExpressions;
323         QList<QDeclarativeParser::Object *> aliasingObjects;
324         QDeclarativeParser::Object *root;
325     };
326     ComponentCompileState compileState;
327
328     struct ComponentStat
329     {
330         ComponentStat() : ids(0), objects(0) {}
331
332         int lineNumber;
333
334         int ids;
335         QList<QDeclarativeParser::LocationSpan> scriptBindings;
336         QList<QDeclarativeParser::LocationSpan> optimizedBindings;
337         int objects;
338     };
339     ComponentStat componentStat;
340
341     void saveComponentState();
342
343     ComponentCompileState componentState(QDeclarativeParser::Object *);
344     QHash<QDeclarativeParser::Object *, ComponentCompileState> savedCompileStates;
345     QList<ComponentStat> savedComponentStats;
346
347     QList<QDeclarativeError> exceptions;
348     QDeclarativeCompiledData *output;
349     QDeclarativeEngine *engine;
350     QDeclarativeEnginePrivate *enginePrivate;
351     QDeclarativeParser::Object *unitRoot;
352     QDeclarativeTypeData *unit;
353 };
354 QT_END_NAMESPACE
355
356 #endif // QDECLARATIVECOMPILER_P_H