1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qdeclarativecompiler_p.h"
43 #include "qdeclarativeengine.h"
44 #include "qdeclarativecomponent.h"
45 #include "qdeclarativecomponent_p.h"
46 #include "qdeclarativecontext.h"
47 #include "qdeclarativecontext_p.h"
48 #ifdef QML_THREADED_VME_INTERPRETER
49 #include "qdeclarativevme_p.h"
52 #include <QtCore/qdebug.h>
54 #include <private/qobject_p.h>
58 int QDeclarativeCompiledData::pack(const char *data, size_t size)
60 const char *p = packData.constData();
61 unsigned int ps = packData.size();
63 for (unsigned int ii = 0; (ii + size) <= ps; ii += sizeof(int)) {
64 if (0 == ::memcmp(p + ii, data, size))
68 int rv = packData.size();
69 packData.append(data, size);
73 int QDeclarativeCompiledData::indexForString(const QString &data)
75 int idx = primitives.indexOf(data);
77 idx = primitives.count();
83 int QDeclarativeCompiledData::indexForByteArray(const QByteArray &data)
85 int idx = datas.indexOf(data);
93 int QDeclarativeCompiledData::indexForUrl(const QUrl &data)
95 int idx = urls.indexOf(data);
103 QDeclarativeCompiledData::QDeclarativeCompiledData(QDeclarativeEngine *engine)
104 : engine(engine), importCache(0), root(0), rootPropertyCache(0)
108 bytecode.reserve(1024);
111 void QDeclarativeCompiledData::destroy()
113 if (engine && hasEngine())
114 QDeclarativeEnginePrivate::deleteInEngineThread(engine, this);
119 QDeclarativeCompiledData::~QDeclarativeCompiledData()
123 for (int ii = 0; ii < types.count(); ++ii) {
124 if (types.at(ii).component)
125 types.at(ii).component->release();
126 if (types.at(ii).typePropertyCache)
127 types.at(ii).typePropertyCache->release();
130 for (int ii = 0; ii < propertyCaches.count(); ++ii)
131 propertyCaches.at(ii)->release();
133 for (int ii = 0; ii < contextCaches.count(); ++ii)
134 contextCaches.at(ii)->release();
136 for (int ii = 0; ii < scripts.count(); ++ii)
137 scripts.at(ii)->release();
140 importCache->release();
142 if (rootPropertyCache)
143 rootPropertyCache->release();
146 void QDeclarativeCompiledData::clear()
148 for (int ii = 0; ii < v8bindings.count(); ++ii)
149 qPersistentDispose(v8bindings[ii]);
153 const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const
156 return type->metaObject();
159 return component->root;
164 Returns the property cache, if one alread exists. The cache is not referenced.
166 QDeclarativePropertyCache *QDeclarativeCompiledData::TypeReference::propertyCache() const
169 return typePropertyCache;
171 return component->rootPropertyCache;
175 Returns the property cache, creating one if it doesn't already exist. The cache is not referenced.
177 QDeclarativePropertyCache *QDeclarativeCompiledData::TypeReference::createPropertyCache(QDeclarativeEngine *engine)
179 if (typePropertyCache) {
180 return typePropertyCache;
182 typePropertyCache = QDeclarativeEnginePrivate::get(engine)->cache(type->metaObject());
183 typePropertyCache->addref();
184 return typePropertyCache;
186 return component->rootPropertyCache;
191 void QDeclarativeCompiledData::dumpInstructions()
195 qWarning().nospace() << "Index\tOperation\t\tData1\tData2\tData3\tComments";
196 qWarning().nospace() << "-------------------------------------------------------------------------------";
198 const char *instructionStream = bytecode.constData();
199 const char *endInstructionStream = bytecode.constData() + bytecode.size();
201 int instructionCount = 0;
202 while (instructionStream < endInstructionStream) {
203 QDeclarativeInstruction *instr = (QDeclarativeInstruction *)instructionStream;
204 dump(instr, instructionCount);
205 instructionStream += QDeclarativeInstruction::size(instructionType(instr));
209 qWarning().nospace() << "-------------------------------------------------------------------------------";
212 int QDeclarativeCompiledData::addInstructionHelper(QDeclarativeInstruction::Type type, QDeclarativeInstruction &instr)
214 #ifdef QML_THREADED_VME_INTERPRETER
215 instr.common.code = QDeclarativeVME::instructionJumpTable()[static_cast<int>(type)];
217 instr.common.instructionType = type;
219 int ptrOffset = bytecode.size();
220 int size = QDeclarativeInstruction::size(type);
221 if (bytecode.capacity() <= bytecode.size() + size)
222 bytecode.reserve(bytecode.size() + size + 512);
223 bytecode.append(reinterpret_cast<const char *>(&instr), size);
227 int QDeclarativeCompiledData::nextInstructionIndex()
229 return bytecode.size();
232 QDeclarativeInstruction *QDeclarativeCompiledData::instruction(int index)
234 return (QDeclarativeInstruction *)(bytecode.constData() + index);
237 QDeclarativeInstruction::Type QDeclarativeCompiledData::instructionType(const QDeclarativeInstruction *instr)
239 #ifdef QML_THREADED_VME_INTERPRETER
240 void **jumpTable = QDeclarativeVME::instructionJumpTable();
241 void *code = instr->common.code;
243 # define QML_CHECK_INSTR_CODE(I, FMT) \
244 if (jumpTable[static_cast<int>(QDeclarativeInstruction::I)] == code) \
245 return QDeclarativeInstruction::I;
247 FOR_EACH_QML_INSTR(QML_CHECK_INSTR_CODE)
248 Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid instruction address");
249 return static_cast<QDeclarativeInstruction::Type>(0);
250 # undef QML_CHECK_INSTR_CODE
252 return static_cast<QDeclarativeInstruction::Type>(instr->common.instructionType);
256 void QDeclarativeCompiledData::initialize(QDeclarativeEngine *engine)
258 Q_ASSERT(!hasEngine());
259 QDeclarativeCleanup::addToEngine(engine);