aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-07-10 10:46:05 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-07-11 17:22:52 +0200
commitde0d91abbbcf58a66018a08ca77bb4d63a5efda1 (patch)
treee960c18118f09b793b54c6767d0ffd4633da7d9d /src/qml/compiler
parent1948139d4c7c76817e13334e8528b01093afa69d (diff)
Split compiler and runtime more clearly
Provide different export macros and different top level headers for each, don't include runtime headers from compiler sources. Change-Id: I7dc3f8c95839a00a871ba045ec65af87123154be Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/compiler.pri8
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h16
-rw-r--r--src/qml/compiler/qv4alloca_p.h108
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h5
-rw-r--r--src/qml/compiler/qv4calldata_p.h123
-rw-r--r--src/qml/compiler/qv4codegen.cpp1
-rw-r--r--src/qml/compiler/qv4codegen_p.h3
-rw-r--r--src/qml/compiler/qv4compileddata_p.h1326
-rw-r--r--src/qml/compiler/qv4compiler.cpp2
-rw-r--r--src/qml/compiler/qv4compiler_p.h9
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h6
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h1
-rw-r--r--src/qml/compiler/qv4compilerglobal_p.h (renamed from src/qml/compiler/qv4stringtoarrayindex_p.h)48
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/compiler/qv4staticvalue_p.h548
16 files changed, 43 insertions, 2165 deletions
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri
index c6ae8c6b69..4d6926d420 100644
--- a/src/qml/compiler/compiler.pri
+++ b/src/qml/compiler/compiler.pri
@@ -2,21 +2,17 @@ INCLUDEPATH += $$PWD
INCLUDEPATH += $$OUT_PWD
HEADERS += \
- $$PWD/qv4alloca_p.h \
$$PWD/qv4bytecodegenerator_p.h \
- $$PWD/qv4compileddata_p.h \
$$PWD/qv4compiler_p.h \
$$PWD/qv4compilercontext_p.h \
$$PWD/qv4compilercontrolflow_p.h \
+ $$PWD/qv4compilerglobal_p.h \
$$PWD/qv4compilerscanfunctions_p.h \
$$PWD/qv4codegen_p.h \
$$PWD/qqmlirbuilder_p.h \
$$PWD/qv4instr_moth_p.h \
$$PWD/qv4bytecodehandler_p.h \
- $$PWD/qv4calldata_p.h \
- $$PWD/qv4util_p.h \
- $$PWD/qv4staticvalue_p.h \
- $$PWD/qv4stringtoarrayindex_p.h
+ $$PWD/qv4util_p.h
SOURCES += \
$$PWD/qv4bytecodegenerator.cpp \
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 82b9050c0b..c366c8e459 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -280,7 +280,7 @@ struct Function
Function *next;
};
-struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
+struct Q_QMLCOMPILER_PRIVATE_EXPORT CompiledFunctionOrExpression
{
CompiledFunctionOrExpression()
{}
@@ -291,7 +291,7 @@ struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
CompiledFunctionOrExpression *next = nullptr;
};
-struct Q_QML_PRIVATE_EXPORT Object
+struct Q_QMLCOMPILER_PRIVATE_EXPORT Object
{
Q_DECLARE_TR_FUNCTIONS(Object)
public:
@@ -367,7 +367,7 @@ private:
PoolList<Function> *functions;
};
-struct Q_QML_PRIVATE_EXPORT Pragma
+struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma
{
enum PragmaType {
PragmaSingleton = 0x1
@@ -377,7 +377,7 @@ struct Q_QML_PRIVATE_EXPORT Pragma
QV4::CompiledData::Location location;
};
-struct Q_QML_PRIVATE_EXPORT Document
+struct Q_QMLCOMPILER_PRIVATE_EXPORT Document
{
Document(bool debugMode);
QString code;
@@ -395,7 +395,7 @@ struct Q_QML_PRIVATE_EXPORT Document
QString stringAt(int index) const { return jsGenerator.stringForIndex(index); }
};
-class Q_QML_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
+class Q_QMLCOMPILER_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
{
QmlIR::Document *document;
QQmlJS::Engine *engine;
@@ -409,7 +409,7 @@ public:
void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column) override;
};
-struct Q_QML_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor
+struct Q_QMLCOMPILER_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor
{
Q_DECLARE_TR_FUNCTIONS(QQmlCodeGenerator)
public:
@@ -513,7 +513,7 @@ public:
QV4::Compiler::JSUnitGenerator *jsGenerator;
};
-struct Q_QML_PRIVATE_EXPORT QmlUnitGenerator
+struct Q_QMLCOMPILER_PRIVATE_EXPORT QmlUnitGenerator
{
void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher());
@@ -522,7 +522,7 @@ private:
char *writeBindings(char *bindingPtr, const Object *o, BindingFilter filter) const;
};
-struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
+struct Q_QMLCOMPILER_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
{
JSCodeGen(Document *document, const QSet<QString> &globalNames);
diff --git a/src/qml/compiler/qv4alloca_p.h b/src/qml/compiler/qv4alloca_p.h
deleted file mode 100644
index 65c3e4d65a..0000000000
--- a/src/qml/compiler/qv4alloca_p.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4_ALLOCA_H
-#define QV4_ALLOCA_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qglobal_p.h>
-
-#if QT_CONFIG(alloca_h)
-# include <alloca.h>
-#elif QT_CONFIG(alloca_malloc_h)
-# include <malloc.h>
-// This does not matter unless compiling in strict standard mode.
-# ifdef Q_CC_MSVC
-# define alloca _alloca
-# endif
-#else
-# include <stdlib.h>
-#endif
-
-// Define Q_ALLOCA_VAR macro to be used instead of #ifdeffing
-// the occurrences of alloca() in case it's not supported.
-// Q_ALLOCA_DECLARE and Q_ALLOCA_ASSIGN macros separate
-// memory allocation from the declaration and RAII.
-#define Q_ALLOCA_VAR(type, name, size) \
- Q_ALLOCA_DECLARE(type, name); \
- Q_ALLOCA_ASSIGN(type, name, size)
-
-#if QT_CONFIG(alloca)
-
-#define Q_ALLOCA_DECLARE(type, name) \
- type *name = 0
-
-#define Q_ALLOCA_ASSIGN(type, name, size) \
- name = static_cast<type*>(alloca(size))
-
-#else
-QT_BEGIN_NAMESPACE
-class Qt_AllocaWrapper
-{
-public:
- Qt_AllocaWrapper() { m_data = 0; }
- ~Qt_AllocaWrapper() { free(m_data); }
- void *data() { return m_data; }
- void allocate(int size) { m_data = malloc(size); memset(m_data, 0, size); }
-private:
- void *m_data;
-};
-QT_END_NAMESPACE
-
-#define Q_ALLOCA_DECLARE(type, name) \
- Qt_AllocaWrapper _qt_alloca_##name; \
- type *name = nullptr
-
-#define Q_ALLOCA_ASSIGN(type, name, size) \
- _qt_alloca_##name.allocate(size); \
- name = static_cast<type*>(_qt_alloca_##name.data())
-
-#endif
-
-#endif
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index acd4aa62ea..8c509dd9f1 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -62,6 +62,11 @@ class SourceLocation;
}
namespace QV4 {
+
+namespace Compiler {
+struct Context;
+}
+
namespace Moth {
class BytecodeGenerator {
diff --git a/src/qml/compiler/qv4calldata_p.h b/src/qml/compiler/qv4calldata_p.h
deleted file mode 100644
index 5a5280cb86..0000000000
--- a/src/qml/compiler/qv4calldata_p.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4CALLDATA_P_H
-#define QV4CALLDATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qv4staticvalue_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-struct CallData
-{
- enum Offsets {
- Function = 0,
- Context = 1,
- Accumulator = 2,
- This = 3,
- NewTarget = 4,
- Argc = 5,
-
- LastOffset = Argc,
- OffsetCount = LastOffset + 1
- };
-
- StaticValue function;
- StaticValue context;
- StaticValue accumulator;
- StaticValue thisObject;
- StaticValue newTarget;
- StaticValue _argc;
-
- int argc() const {
- Q_ASSERT(_argc.isInteger());
- return _argc.int_32();
- }
-
- void setArgc(int argc) {
- Q_ASSERT(argc >= 0);
- _argc.setInt_32(argc);
- }
-
- inline ReturnedValue argument(int i) const {
- return i < argc() ? args[i].asReturnedValue()
- : StaticValue::undefinedValue().asReturnedValue();
- }
-
- StaticValue args[1];
-
- static Q_DECL_CONSTEXPR int HeaderSize()
- {
- return offsetof(CallData, args) / sizeof(QV4::StaticValue);
- }
-
- template<typename Value>
- Value *argValues();
-
- template<typename Value>
- const Value *argValues() const;
-};
-
-Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value);
-Q_STATIC_ASSERT(offsetof(CallData, function ) == CallData::Function * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, context ) == CallData::Context * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, accumulator) == CallData::Accumulator * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, thisObject ) == CallData::This * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, newTarget ) == CallData::NewTarget * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, _argc ) == CallData::Argc * sizeof(StaticValue));
-Q_STATIC_ASSERT(offsetof(CallData, args ) == 6 * sizeof(StaticValue));
-
-} // namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // QV4CALLDATA_P_H
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 86617aa428..c43ea64e2e 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -48,7 +48,6 @@
#include <private/qqmljsast_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
-#include <private/qv4stringtoarrayindex_p.h>
#include <private/qv4staticvalue_p.h>
#include <private/qv4compilercontext_p.h>
#include <private/qv4compilercontrolflow_p.h>
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 491ecb2a0d..82a4fc3289 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -50,7 +50,6 @@
// We mean it.
//
-#include "private/qv4global_p.h"
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsengine_p.h>
#include <private/qqmljsast_p.h>
@@ -79,7 +78,7 @@ struct ControlFlow;
struct ControlFlowCatch;
struct ControlFlowFinally;
-class Q_QML_PRIVATE_EXPORT Codegen: protected QQmlJS::AST::Visitor
+class Q_QMLCOMPILER_PRIVATE_EXPORT Codegen: protected QQmlJS::AST::Visitor
{
protected:
using BytecodeGenerator = QV4::Moth::BytecodeGenerator;
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
deleted file mode 100644
index 60d0c50599..0000000000
--- a/src/qml/compiler/qv4compileddata_p.h
+++ /dev/null
@@ -1,1326 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4COMPILEDDATA_P_H
-#define QV4COMPILEDDATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <functional>
-
-#include <QtCore/qstring.h>
-#include <QtCore/qscopeguard.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qhash.h>
-
-#if QT_CONFIG(temporaryfile)
-#include <QtCore/qsavefile.h>
-#endif
-
-#include <private/qendian_p.h>
-#include <private/qv4staticvalue_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Bump this whenever the compiler data structures change in an incompatible way.
-//
-// IMPORTANT:
-//
-// Also change the comment behind the number to describe the latest change. This has the added
-// benefit that if another patch changes the version too, it will result in a merge conflict, and
-// not get removed silently.
-#define QV4_DATA_STRUCTURE_VERSION 0x24 // Collect function parameter types
-
-class QIODevice;
-class QQmlTypeNameCache;
-class QQmlType;
-class QQmlEngine;
-
-namespace QmlIR {
-struct Document;
-}
-
-namespace QV4 {
-namespace Heap {
-struct Module;
-struct String;
-struct InternalClass;
-};
-
-struct Function;
-class EvalISelFactory;
-
-namespace CompiledData {
-
-struct String;
-struct Function;
-struct Lookup;
-struct RegExp;
-struct Unit;
-
-template <typename ItemType, typename Container, const ItemType *(Container::*IndexedGetter)(int index) const>
-struct TableIterator
-{
- TableIterator(const Container *container, int index) : container(container), index(index) {}
- const Container *container;
- int index;
-
- const ItemType *operator->() { return (container->*IndexedGetter)(index); }
- void operator++() { ++index; }
- bool operator==(const TableIterator &rhs) const { return index == rhs.index; }
- bool operator!=(const TableIterator &rhs) const { return index != rhs.index; }
-};
-
-struct Location
-{
- union {
- quint32 _dummy;
- quint32_le_bitfield<0, 20> line;
- quint32_le_bitfield<20, 12> column;
- };
-
- Location() : _dummy(0) { }
-
- inline bool operator<(const Location &other) const {
- return line < other.line ||
- (line == other.line && column < other.column);
- }
-};
-static_assert(sizeof(Location) == 4, "Location structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct RegExp
-{
- enum Flags : unsigned int {
- RegExp_NoFlags = 0x0,
- RegExp_Global = 0x01,
- RegExp_IgnoreCase = 0x02,
- RegExp_Multiline = 0x04,
- RegExp_Unicode = 0x08,
- RegExp_Sticky = 0x10
- };
- union {
- quint32 _dummy;
- quint32_le_bitfield<0, 5> flags;
- quint32_le_bitfield<5, 27> stringIndex;
- };
-
- RegExp() : _dummy(0) { }
-};
-static_assert(sizeof(RegExp) == 4, "RegExp structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Lookup
-{
- enum Type : unsigned int {
- Type_Getter = 0,
- Type_Setter = 1,
- Type_GlobalGetter = 2,
- Type_QmlContextPropertyGetter = 3
- };
-
- union {
- quint32 _dummy;
- quint32_le_bitfield<0, 4> type_and_flags;
- quint32_le_bitfield<4, 28> nameIndex;
- };
-
- Lookup() : _dummy(0) { }
-};
-static_assert(sizeof(Lookup) == 4, "Lookup structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct JSClassMember
-{
- union {
- quint32 _dummy;
- quint32_le_bitfield<0, 31> nameOffset;
- quint32_le_bitfield<31, 1> isAccessor;
- };
-
- JSClassMember() : _dummy(0) { }
-};
-static_assert(sizeof(JSClassMember) == 4, "JSClassMember structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct JSClass
-{
- quint32_le nMembers;
- // JSClassMember[nMembers]
-
- static int calculateSize(int nMembers) { return (sizeof(JSClass) + nMembers * sizeof(JSClassMember) + 7) & ~7; }
-};
-static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-// This data structure is intended to be binary compatible with QStringData/QStaticStringData on
-// 64-bit and 32-bit little-endian architectures, in all directions. So the same structure mapped
-// from a file must be castable to a QStringData regardless of the pointer size. With the first
-// few fields that's easy, they're always 32-bit. However the offset field of QArrayData is a
-// ptrdiff_t and thus variable in size.
-// On 64-bit systems compilers enforce an 8-byte alignment and thus place it at offset 16, while
-// on 32-bit systems offset 12 is sufficient. Therefore the two values don't overlap and contain
-// the same value.
-struct String
-{
- qint32_le refcount; // -1
- qint32_le size;
- quint32_le allocAndCapacityReservedFlag; // 0
- quint32_le offsetOn32Bit;
- quint64_le offsetOn64Bit;
- // uint16 strdata[]
-
- static int calculateSize(const QString &str) {
- return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7;
- }
-};
-static_assert(sizeof(String) == 24, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-// Ensure compatibility with QString
-static_assert(offsetof(QArrayData, ref) == offsetof(String, refcount), "refcount must be at the same location");
-static_assert(offsetof(QArrayData, size) == offsetof(String, size), "size must be at the same location");
-static_assert(offsetof(String, offsetOn64Bit) == 16, "offset must be at 8-byte aligned location");
-static_assert(offsetof(String, offsetOn32Bit) == 12, "offset must be at 4-byte aligned location");
-#if QT_POINTER_SIZE == 8
-static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn64Bit), "offset must be at the same location");
-#else
-static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn32Bit), "offset must be at the same location");
-#endif
-
-struct CodeOffsetToLine {
- quint32_le codeOffset;
- quint32_le line;
-};
-static_assert(sizeof(CodeOffsetToLine) == 8, "CodeOffsetToLine structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Block
-{
- quint32_le nLocals;
- quint32_le localsOffset;
- quint16_le sizeOfLocalTemporalDeadZone;
- quint16_le padding;
-
- const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
-
- static int calculateSize(int nLocals) {
- int trailingData = nLocals*sizeof (quint32);
- size_t size = align(align(sizeof(Block)) + size_t(trailingData));
- Q_ASSERT(size < INT_MAX);
- return int(size);
- }
-
- static size_t align(size_t a) {
- return (a + 7) & ~size_t(7);
- }
-};
-static_assert(sizeof(Block) == 12, "Block structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-enum class BuiltinType : unsigned int {
- Var = 0, Variant, Int, Bool, Real, String, Url, Color,
- Font, Time, Date, DateTime, Rect, Point, Size,
- Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, InvalidBuiltin
-};
-
-struct ParameterType
-{
- union {
- quint32 _dummy;
- quint32_le_bitfield<0, 1> indexIsBuiltinType;
- quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType;
- };
-};
-static_assert(sizeof(ParameterType) == 4, "ParameterType structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Parameter
-{
- quint32_le nameIndex;
- ParameterType type;
-};
-static_assert(sizeof(Parameter) == 8, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-// Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties
-// for unaligned access. The ordering of the fields is also from largest to smallest.
-struct Function
-{
- enum Flags : unsigned int {
- IsStrict = 0x1,
- IsArrowFunction = 0x2,
- IsGenerator = 0x4
- };
-
- // Absolute offset into file where the code for this function is located.
- quint32_le codeOffset;
- quint32_le codeSize;
-
- quint32_le nameIndex;
- quint16_le length;
- quint16_le nFormals;
- quint32_le formalsOffset; // Can't turn this into a calculated offset because of the mutation in CompilationUnit::createUnitData.
- ParameterType returnType;
- quint32_le localsOffset;
- quint16_le nLocals;
- quint16_le nLineNumbers;
- size_t lineNumberOffset() const { return localsOffset + nLocals * sizeof(quint32); }
- quint32_le nestedFunctionIndex; // for functions that only return a single closure, used in signal handlers
- quint16_le sizeOfLocalTemporalDeadZone;
- quint16_le firstTemporalDeadZoneRegister;
- quint16_le sizeOfRegisterTemporalDeadZone;
- quint16_le nRegisters;
- Location location;
-
- quint32_le nLabelInfos;
- size_t labelInfosOffset() const { return lineNumberOffset() + nLineNumbers * sizeof(CodeOffsetToLine); }
-
- // Keep all unaligned data at the end
- quint8 flags;
- quint8 padding1;
-
- // quint32 formalsIndex[nFormals]
- // quint32 localsIndex[nLocals]
-
- const Parameter *formalsTable() const { return reinterpret_cast<const Parameter *>(reinterpret_cast<const char *>(this) + formalsOffset); }
- const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
- const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset()); }
-
- // --- QQmlPropertyCacheCreator interface
- const Parameter *formalsBegin() const { return formalsTable(); }
- const Parameter *formalsEnd() const { return formalsTable() + nFormals; }
- // ---
-
- const quint32_le *labelInfoTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + labelInfosOffset()); }
-
- const char *code() const { return reinterpret_cast<const char *>(this) + codeOffset; }
-
- static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int labelInfoSize, int codeSize) {
- int trailingData = nFormals * sizeof(Parameter) + (nLocals + nInnerfunctions + labelInfoSize)*sizeof (quint32)
- + nLines*sizeof(CodeOffsetToLine);
- size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize);
- Q_ASSERT(size < INT_MAX);
- return int(size);
- }
-
- static size_t align(size_t a) {
- return (a + 7) & ~size_t(7);
- }
-};
-static_assert(sizeof(Function) == 56, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Method {
- enum Type {
- Regular,
- Getter,
- Setter
- };
-
- quint32_le name;
- quint32_le type;
- quint32_le function;
-};
-static_assert(sizeof(Method) == 12, "Method structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Class
-{
- quint32_le nameIndex;
- quint32_le scopeIndex;
- quint32_le constructorFunction;
- quint32_le nStaticMethods;
- quint32_le nMethods;
- quint32_le methodTableOffset;
-
- const Method *methodTable() const { return reinterpret_cast<const Method *>(reinterpret_cast<const char *>(this) + methodTableOffset); }
-
- static int calculateSize(int nStaticMethods, int nMethods) {
- int trailingData = (nStaticMethods + nMethods) * sizeof(Method);
- size_t size = align(sizeof(Class) + trailingData);
- Q_ASSERT(size < INT_MAX);
- return int(size);
- }
-
- static size_t align(size_t a) {
- return (a + 7) & ~size_t(7);
- }
-};
-static_assert(sizeof(Class) == 24, "Class structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct TemplateObject
-{
- quint32_le size;
-
- static int calculateSize(int size) {
- int trailingData = 2 * size * sizeof(quint32_le);
- size_t s = align(sizeof(TemplateObject) + trailingData);
- Q_ASSERT(s < INT_MAX);
- return int(s);
- }
-
- static size_t align(size_t a) {
- return (a + 7) & ~size_t(7);
- }
-
- const quint32_le *stringTable() const {
- return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this + 1));
- }
-
- uint stringIndexAt(uint i) const {
- return stringTable()[i];
- }
- uint rawStringIndexAt(uint i) const {
- return stringTable()[size + i];
- }
-};
-static_assert(sizeof(TemplateObject) == 4, "Template object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct ExportEntry
-{
- quint32_le exportName;
- quint32_le moduleRequest;
- quint32_le importName;
- quint32_le localName;
- Location location;
-};
-static_assert(sizeof(ExportEntry) == 20, "ExportEntry structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct ImportEntry
-{
- quint32_le moduleRequest;
- quint32_le importName;
- quint32_le localName;
- Location location;
-};
-static_assert(sizeof(ImportEntry) == 16, "ImportEntry structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-// Qml data structures
-
-struct TranslationData
-{
- quint32_le stringIndex;
- quint32_le commentIndex;
- qint32_le number;
- quint32_le padding;
-};
-static_assert(sizeof(TranslationData) == 16, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Binding
-{
- quint32_le propertyNameIndex;
-
- enum ValueType : unsigned int {
- Type_Invalid,
- Type_Boolean,
- Type_Number,
- Type_String,
- Type_Null,
- Type_Translation,
- Type_TranslationById,
- Type_Script,
- Type_Object,
- Type_AttachedProperty,
- Type_GroupProperty
- };
-
- enum Flags : unsigned int {
- IsSignalHandlerExpression = 0x1,
- IsSignalHandlerObject = 0x2,
- IsOnAssignment = 0x4,
- InitializerForReadOnlyDeclaration = 0x8,
- IsResolvedEnum = 0x10,
- IsListItem = 0x20,
- IsBindingToAlias = 0x40,
- IsDeferredBinding = 0x80,
- IsCustomParserBinding = 0x100,
- IsFunctionExpression = 0x200
- };
-
- union {
- quint32_le_bitfield<0, 16> flags;
- quint32_le_bitfield<16, 16> type;
- };
- union {
- bool b;
- quint32_le constantValueIndex;
- quint32_le compiledScriptIndex; // used when Type_Script
- quint32_le objectIndex;
- quint32_le translationDataIndex; // used when Type_Translation
- quint32 nullMarker;
- } value;
- quint32_le stringIndex; // Set for Type_String and Type_Script (the latter because of script strings)
-
- Location location;
- Location valueLocation;
-
- bool isValueBinding() const
- {
- if (type == Type_AttachedProperty
- || type == Type_GroupProperty)
- return false;
- if (flags & IsSignalHandlerExpression
- || flags & IsSignalHandlerObject)
- return false;
- return true;
- }
-
- bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); }
- bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); }
-
- bool isSignalHandler() const
- {
- if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) {
- Q_ASSERT(!isValueBinding());
- Q_ASSERT(!isAttachedProperty());
- Q_ASSERT(!isGroupProperty());
- return true;
- }
- return false;
- }
-
- bool isAttachedProperty() const
- {
- if (type == Type_AttachedProperty) {
- Q_ASSERT(!isValueBinding());
- Q_ASSERT(!isSignalHandler());
- Q_ASSERT(!isGroupProperty());
- return true;
- }
- return false;
- }
-
- bool isGroupProperty() const
- {
- if (type == Type_GroupProperty) {
- Q_ASSERT(!isValueBinding());
- Q_ASSERT(!isSignalHandler());
- Q_ASSERT(!isAttachedProperty());
- return true;
- }
- return false;
- }
-
- bool isFunctionExpression() const { return (flags & IsFunctionExpression); }
-
- //reverse of Lexer::singleEscape()
- static QString escapedString(const QString &string)
- {
- QString tmp = QLatin1String("\"");
- for (int i = 0; i < string.length(); ++i) {
- const QChar &c = string.at(i);
- switch (c.unicode()) {
- case 0x08:
- tmp += QLatin1String("\\b");
- break;
- case 0x09:
- tmp += QLatin1String("\\t");
- break;
- case 0x0A:
- tmp += QLatin1String("\\n");
- break;
- case 0x0B:
- tmp += QLatin1String("\\v");
- break;
- case 0x0C:
- tmp += QLatin1String("\\f");
- break;
- case 0x0D:
- tmp += QLatin1String("\\r");
- break;
- case 0x22:
- tmp += QLatin1String("\\\"");
- break;
- case 0x27:
- tmp += QLatin1String("\\\'");
- break;
- case 0x5C:
- tmp += QLatin1String("\\\\");
- break;
- default:
- tmp += c;
- break;
- }
- }
- tmp += QLatin1Char('\"');
- return tmp;
- }
-
- bool isTranslationBinding() const { return type == Type_Translation || type == Type_TranslationById; }
- bool evaluatesToString() const { return type == Type_String || isTranslationBinding(); }
-
- bool valueAsBoolean() const
- {
- if (type == Type_Boolean)
- return value.b;
- return false;
- }
-
-};
-
-static_assert(sizeof(Binding) == 24, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct EnumValue
-{
- quint32_le nameIndex;
- qint32_le value;
- Location location;
-};
-static_assert(sizeof(EnumValue) == 12, "EnumValue structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Enum
-{
- quint32_le nameIndex;
- quint32_le nEnumValues;
- Location location;
-
- const EnumValue *enumValueAt(int idx) const {
- return reinterpret_cast<const EnumValue*>(this + 1) + idx;
- }
-
- static int calculateSize(int nEnumValues) {
- return (sizeof(Enum)
- + nEnumValues * sizeof(EnumValue)
- + 7) & ~0x7;
- }
-
- // --- QQmlPropertyCacheCreatorInterface
- const EnumValue *enumValuesBegin() const { return enumValueAt(0); }
- const EnumValue *enumValuesEnd() const { return enumValueAt(nEnumValues); }
- int enumValueCount() const { return nEnumValues; }
- // ---
-};
-static_assert(sizeof(Enum) == 12, "Enum structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Signal
-{
- quint32_le nameIndex;
- quint32_le nParameters;
- Location location;
- // Parameter parameters[1];
-
- const Parameter *parameterAt(int idx) const {
- return reinterpret_cast<const Parameter*>(this + 1) + idx;
- }
-
- static int calculateSize(int nParameters) {
- return (sizeof(Signal)
- + nParameters * sizeof(Parameter)
- + 7) & ~0x7;
- }
-
- // --- QQmlPropertyCacheCceatorInterface
- const Parameter *parametersBegin() const { return parameterAt(0); }
- const Parameter *parametersEnd() const { return parameterAt(nParameters); }
- int parameterCount() const { return nParameters; }
- // ---
-};
-static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Property
-{
- quint32_le nameIndex;
- union {
- quint32_le_bitfield<0, 29> builtinTypeOrTypeNameIndex;
- quint32_le_bitfield<29, 1> isBuiltinType;
- quint32_le_bitfield<30, 1> isList;
- quint32_le_bitfield<31, 1> isReadOnly;
- };
-
- Location location;
-
- void setBuiltinType(BuiltinType t)
- {
- builtinTypeOrTypeNameIndex = static_cast<quint32>(t);
- isBuiltinType = true;
- }
- BuiltinType builtinType() const {
- if (isBuiltinType)
- return static_cast<BuiltinType>(quint32(builtinTypeOrTypeNameIndex));
- return BuiltinType::InvalidBuiltin;
- }
- void setCustomType(int nameIndex)
- {
- builtinTypeOrTypeNameIndex = nameIndex;
- isBuiltinType = false;
- }
-};
-static_assert(sizeof(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Alias {
- enum Flags : unsigned int {
- IsReadOnly = 0x1,
- Resolved = 0x2,
- AliasPointsToPointerObject = 0x4
- };
- union {
- quint32_le_bitfield<0, 29> nameIndex;
- quint32_le_bitfield<29, 3> flags;
- };
- union {
- quint32_le idIndex; // string index
- quint32_le_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues)
- quint32_le_bitfield<31, 1> aliasToLocalAlias;
- };
- union {
- quint32_le propertyNameIndex; // string index
- qint32_le encodedMetaPropertyIndex;
- quint32_le localAliasIndex; // index in list of aliases local to the object (if targetObjectId == objectId)
- };
- Location location;
- Location referenceLocation;
-
- bool isObjectAlias() const {
- Q_ASSERT(flags & Resolved);
- return encodedMetaPropertyIndex == -1;
- }
-};
-static_assert(sizeof(Alias) == 20, "Alias structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Object
-{
- enum Flags : unsigned int {
- NoFlag = 0x0,
- IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary
- HasDeferredBindings = 0x2, // any of the bindings are deferred
- HasCustomParserBindings = 0x4
- };
-
- // Depending on the use, this may be the type name to instantiate before instantiating this
- // object. For grouped properties the type name will be empty and for attached properties
- // it will be the name of the attached type.
- quint32_le inheritedTypeNameIndex;
- quint32_le idNameIndex;
- union {
- quint32_le_bitfield<0, 15> flags;
- quint32_le_bitfield<15, 1> defaultPropertyIsAlias;
- qint32_le_bitfield<16, 16> id;
- };
- qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object
- quint16_le nFunctions;
- quint16_le nProperties;
- quint32_le offsetToFunctions;
- quint32_le offsetToProperties;
- quint32_le offsetToAliases;
- quint16_le nAliases;
- quint16_le nEnums;
- quint32_le offsetToEnums; // which in turn will be a table with offsets to variable-sized Enum objects
- quint32_le offsetToSignals; // which in turn will be a table with offsets to variable-sized Signal objects
- quint16_le nSignals;
- quint16_le nBindings;
- quint32_le offsetToBindings;
- quint32_le nNamedObjectsInComponent;
- quint32_le offsetToNamedObjectsInComponent;
- Location location;
- Location locationOfIdProperty;
-// Function[]
-// Property[]
-// Signal[]
-// Binding[]
-
- static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent)
- {
- return ( sizeof(Object)
- + nFunctions * sizeof(quint32)
- + nProperties * sizeof(Property)
- + nAliases * sizeof(Alias)
- + nEnums * sizeof(quint32)
- + nSignals * sizeof(quint32)
- + nBindings * sizeof(Binding)
- + nNamedObjectsInComponent * sizeof(int)
- + 0x7
- ) & ~0x7;
- }
-
- const quint32_le *functionOffsetTable() const
- {
- return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToFunctions);
- }
-
- const Property *propertyTable() const
- {
- return reinterpret_cast<const Property*>(reinterpret_cast<const char *>(this) + offsetToProperties);
- }
-
- const Alias *aliasTable() const
- {
- return reinterpret_cast<const Alias*>(reinterpret_cast<const char *>(this) + offsetToAliases);
- }
-
- const Binding *bindingTable() const
- {
- return reinterpret_cast<const Binding*>(reinterpret_cast<const char *>(this) + offsetToBindings);
- }
-
- const Enum *enumAt(int idx) const
- {
- const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToEnums);
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Enum*>(reinterpret_cast<const char*>(this) + offset);
- }
-
- const Signal *signalAt(int idx) const
- {
- const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToSignals);
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Signal*>(reinterpret_cast<const char*>(this) + offset);
- }
-
- const quint32_le *namedObjectsInComponentTable() const
- {
- return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToNamedObjectsInComponent);
- }
-
- // --- QQmlPropertyCacheCreator interface
- int propertyCount() const { return nProperties; }
- int aliasCount() const { return nAliases; }
- int enumCount() const { return nEnums; }
- int signalCount() const { return nSignals; }
- int functionCount() const { return nFunctions; }
-
- const Binding *bindingsBegin() const { return bindingTable(); }
- const Binding *bindingsEnd() const { return bindingTable() + nBindings; }
-
- const Property *propertiesBegin() const { return propertyTable(); }
- const Property *propertiesEnd() const { return propertyTable() + nProperties; }
-
- const Alias *aliasesBegin() const { return aliasTable(); }
- const Alias *aliasesEnd() const { return aliasTable() + nAliases; }
-
- typedef TableIterator<Enum, Object, &Object::enumAt> EnumIterator;
- EnumIterator enumsBegin() const { return EnumIterator(this, 0); }
- EnumIterator enumsEnd() const { return EnumIterator(this, nEnums); }
-
- typedef TableIterator<Signal, Object, &Object::signalAt> SignalIterator;
- SignalIterator signalsBegin() const { return SignalIterator(this, 0); }
- SignalIterator signalsEnd() const { return SignalIterator(this, nSignals); }
-
- int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
- // ---
-};
-static_assert(sizeof(Object) == 68, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct Import
-{
- enum ImportType : unsigned int {
- ImportLibrary = 0x1,
- ImportFile = 0x2,
- ImportScript = 0x3
- };
- quint32_le type;
-
- quint32_le uriIndex;
- quint32_le qualifierIndex;
-
- qint32_le majorVersion;
- qint32_le minorVersion;
-
- Location location;
-
- Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; }
-};
-static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct QmlUnit
-{
- quint32_le nImports;
- quint32_le offsetToImports;
- quint32_le nObjects;
- quint32_le offsetToObjects;
-
- const Import *importAt(int idx) const {
- return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import));
- }
-
- const Object *objectAt(int idx) const {
- const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToObjects);
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Object*>(reinterpret_cast<const char*>(this) + offset);
- }
-};
-static_assert(sizeof(QmlUnit) == 16, "QmlUnit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-enum { QmlCompileHashSpace = 48 };
-static const char magic_str[] = "qv4cdata";
-
-struct Unit
-{
- // DO NOT CHANGE THESE FIELDS EVER
- char magic[8];
- quint32_le version;
- quint32_le qtVersion;
- qint64_le sourceTimeStamp;
- quint32_le unitSize; // Size of the Unit and any depending data.
- // END DO NOT CHANGE THESE FIELDS EVER
-
- char libraryVersionHash[QmlCompileHashSpace];
-
- char md5Checksum[16]; // checksum of all bytes following this field.
- char dependencyMD5Checksum[16];
-
- enum : unsigned int {
- IsJavascript = 0x1,
- StaticData = 0x2, // Unit data persistent in memory?
- IsSingleton = 0x4,
- IsSharedLibrary = 0x8, // .pragma shared?
- IsESModule = 0x10,
- PendingTypeCompilation = 0x20 // the QML data structures present are incomplete and require type compilation
- };
- quint32_le flags;
- quint32_le stringTableSize;
- quint32_le offsetToStringTable;
- quint32_le functionTableSize;
- quint32_le offsetToFunctionTable;
- quint32_le classTableSize;
- quint32_le offsetToClassTable;
- quint32_le templateObjectTableSize;
- quint32_le offsetToTemplateObjectTable;
- quint32_le blockTableSize;
- quint32_le offsetToBlockTable;
- quint32_le lookupTableSize;
- quint32_le offsetToLookupTable;
- quint32_le regexpTableSize;
- quint32_le offsetToRegexpTable;
- quint32_le constantTableSize;
- quint32_le offsetToConstantTable;
- quint32_le jsClassTableSize;
- quint32_le offsetToJSClassTable;
- quint32_le translationTableSize;
- quint32_le offsetToTranslationTable;
- quint32_le localExportEntryTableSize;
- quint32_le offsetToLocalExportEntryTable;
- quint32_le indirectExportEntryTableSize;
- quint32_le offsetToIndirectExportEntryTable;
- quint32_le starExportEntryTableSize;
- quint32_le offsetToStarExportEntryTable;
- quint32_le importEntryTableSize;
- quint32_le offsetToImportEntryTable;
- quint32_le moduleRequestTableSize;
- quint32_le offsetToModuleRequestTable;
- qint32_le indexOfRootFunction;
- quint32_le sourceFileIndex;
- quint32_le finalUrlIndex;
-
- quint32_le offsetToQmlUnit;
-
- /* QML specific fields */
-
- const QmlUnit *qmlUnit() const {
- return reinterpret_cast<const QmlUnit *>(reinterpret_cast<const char *>(this) + offsetToQmlUnit);
- }
-
- QmlUnit *qmlUnit() {
- return reinterpret_cast<QmlUnit *>(reinterpret_cast<char *>(this) + offsetToQmlUnit);
- }
-
- bool isSingleton() const {
- return flags & Unit::IsSingleton;
- }
- /* end QML specific fields*/
-
- QString stringAtInternal(int idx) const {
- Q_ASSERT(idx < int(stringTableSize));
- const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
- const quint32_le offset = offsetTable[idx];
- const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
- if (str->size == 0)
- return QString();
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- if (flags & StaticData) {
- const QStringDataPtr holder = { const_cast<QStringData *>(reinterpret_cast<const QStringData*>(str)) };
- return QString(holder);
- }
- const QChar *characters = reinterpret_cast<const QChar *>(str + 1);
- return QString(characters, str->size);
-#else
- const quint16_le *characters = reinterpret_cast<const quint16_le *>(str + 1);
- QString qstr(str->size, Qt::Uninitialized);
- QChar *ch = qstr.data();
- for (int i = 0; i < str->size; ++i)
- ch[i] = QChar(characters[i]);
- return qstr;
-#endif
- }
-
- const quint32_le *functionOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToFunctionTable); }
- const quint32_le *classOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToClassTable); }
- const quint32_le *templateObjectOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToTemplateObjectTable); }
- const quint32_le *blockOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToBlockTable); }
-
- const Function *functionAt(int idx) const {
- const quint32_le *offsetTable = functionOffsetTable();
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Function*>(reinterpret_cast<const char *>(this) + offset);
- }
-
- const Class *classAt(int idx) const {
- const quint32_le *offsetTable = classOffsetTable();
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Class *>(reinterpret_cast<const char *>(this) + offset);
- }
-
- const TemplateObject *templateObjectAt(int idx) const {
- const quint32_le *offsetTable = templateObjectOffsetTable();
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const TemplateObject *>(reinterpret_cast<const char *>(this) + offset);
- }
-
- const Block *blockAt(int idx) const {
- const quint32_le *offsetTable = blockOffsetTable();
- const quint32_le offset = offsetTable[idx];
- return reinterpret_cast<const Block *>(reinterpret_cast<const char *>(this) + offset);
- }
-
- const Lookup *lookupTable() const { return reinterpret_cast<const Lookup*>(reinterpret_cast<const char *>(this) + offsetToLookupTable); }
- const RegExp *regexpAt(int index) const {
- return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp));
- }
- const quint64_le *constants() const {
- return reinterpret_cast<const quint64_le*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
- }
-
- const JSClassMember *jsClassAt(int idx, int *nMembers) const {
- const quint32_le *offsetTable = reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + offsetToJSClassTable);
- const quint32_le offset = offsetTable[idx];
- const char *ptr = reinterpret_cast<const char *>(this) + offset;
- const JSClass *klass = reinterpret_cast<const JSClass *>(ptr);
- *nMembers = klass->nMembers;
- return reinterpret_cast<const JSClassMember*>(ptr + sizeof(JSClass));
- }
-
- const TranslationData *translations() const {
- return reinterpret_cast<const TranslationData *>(reinterpret_cast<const char *>(this) + offsetToTranslationTable);
- }
-
- const ImportEntry *importEntryTable() const { return reinterpret_cast<const ImportEntry *>(reinterpret_cast<const char *>(this) + offsetToImportEntryTable); }
- const ExportEntry *localExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToLocalExportEntryTable); }
- const ExportEntry *indirectExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToIndirectExportEntryTable); }
- const ExportEntry *starExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToStarExportEntryTable); }
-
- const quint32_le *moduleRequestTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToModuleRequestTable); }
-};
-
-static_assert(sizeof(Unit) == 248, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-
-struct TypeReference
-{
- TypeReference(const Location &loc)
- : location(loc)
- , needsCreation(false)
- , errorWhenNotFound(false)
- {}
- Location location; // first use
- bool needsCreation : 1; // whether the type needs to be creatable or not
- bool errorWhenNotFound: 1;
-};
-
-// Map from name index to location of first use.
-struct TypeReferenceMap : QHash<int, TypeReference>
-{
- TypeReference &add(int nameIndex, const Location &loc) {
- Iterator it = find(nameIndex);
- if (it != end())
- return *it;
- return *insert(nameIndex, loc);
- }
-
- template <typename CompiledObject>
- void collectFromObject(const CompiledObject *obj)
- {
- if (obj->inheritedTypeNameIndex != 0) {
- TypeReference &r = this->add(obj->inheritedTypeNameIndex, obj->location);
- r.needsCreation = true;
- r.errorWhenNotFound = true;
- }
-
- auto prop = obj->propertiesBegin();
- auto propEnd = obj->propertiesEnd();
- for ( ; prop != propEnd; ++prop) {
- if (!prop->isBuiltinType) {
- TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location);
- r.errorWhenNotFound = true;
- }
- }
-
- auto binding = obj->bindingsBegin();
- auto bindingEnd = obj->bindingsEnd();
- for ( ; binding != bindingEnd; ++binding) {
- if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty)
- this->add(binding->propertyNameIndex, binding->location);
- }
- }
-
- template <typename Iterator>
- void collectFromObjects(Iterator it, Iterator end)
- {
- for (; it != end; ++it)
- collectFromObject(*it);
- }
-};
-
-using DependentTypesHasher = std::function<QByteArray()>;
-
-// This is how this hooks into the existing structures:
-
-struct CompilationUnitBase
-{
- Q_DISABLE_COPY(CompilationUnitBase)
-
- CompilationUnitBase() = default;
- ~CompilationUnitBase() = default;
-
- CompilationUnitBase(CompilationUnitBase &&other) noexcept { *this = std::move(other); }
-
- CompilationUnitBase &operator=(CompilationUnitBase &&other) noexcept
- {
- if (this != &other) {
- runtimeStrings = other.runtimeStrings;
- other.runtimeStrings = nullptr;
- constants = other.constants;
- other.constants = nullptr;
- runtimeRegularExpressions = other.runtimeRegularExpressions;
- other.runtimeRegularExpressions = nullptr;
- runtimeClasses = other.runtimeClasses;
- other.runtimeClasses = nullptr;
- imports = other.imports;
- other.imports = nullptr;
- }
- return *this;
- }
-
- // pointers either to data->constants() or little-endian memory copy.
- QV4::Heap::String **runtimeStrings = nullptr; // Array
- const StaticValue* constants = nullptr;
- QV4::StaticValue *runtimeRegularExpressions = nullptr;
- QV4::Heap::InternalClass **runtimeClasses = nullptr;
- const StaticValue** imports = nullptr;
-};
-
-Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0);
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, constants) == sizeof(QV4::Heap::String **));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offsetof(CompilationUnitBase, constants) + sizeof(const StaticValue *));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeClasses) == offsetof(CompilationUnitBase, runtimeRegularExpressions) + sizeof(const StaticValue *));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, imports) == offsetof(CompilationUnitBase, runtimeClasses) + sizeof(const StaticValue *));
-
-struct CompilationUnit : public CompilationUnitBase
-{
- Q_DISABLE_COPY(CompilationUnit)
-
- const Unit *data = nullptr;
- const QmlUnit *qmlData = nullptr;
- QStringList dynamicStrings;
-public:
- using CompiledObject = CompiledData::Object;
-
- CompilationUnit(const Unit *unitData = nullptr, const QString &fileName = QString(),
- const QString &finalUrlString = QString())
- {
- setUnitData(unitData, nullptr, fileName, finalUrlString);
- }
-
- ~CompilationUnit()
- {
- if (data) {
- if (data->qmlUnit() != qmlData)
- free(const_cast<QmlUnit *>(qmlData));
- qmlData = nullptr;
-
- if (!(data->flags & QV4::CompiledData::Unit::StaticData))
- free(const_cast<Unit *>(data));
- }
- data = nullptr;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- delete [] constants;
- constants = nullptr;
-#endif
-
- delete [] imports;
- imports = nullptr;
- }
-
- CompilationUnit(CompilationUnit &&other) noexcept
- {
- *this = std::move(other);
- }
-
- CompilationUnit &operator=(CompilationUnit &&other) noexcept
- {
- if (this != &other) {
- data = other.data;
- other.data = nullptr;
- qmlData = other.qmlData;
- other.qmlData = nullptr;
- dynamicStrings = std::move(other.dynamicStrings);
- other.dynamicStrings.clear();
- m_fileName = std::move(other.m_fileName);
- other.m_fileName.clear();
- m_finalUrlString = std::move(other.m_finalUrlString);
- other.m_finalUrlString.clear();
- m_module = other.m_module;
- other.m_module = nullptr;
- CompilationUnitBase::operator=(std::move(other));
- }
- return *this;
- }
-
- const Unit *unitData() const { return data; }
-
- void setUnitData(const Unit *unitData, const QmlUnit *qmlUnit = nullptr,
- const QString &fileName = QString(), const QString &finalUrlString = QString())
- {
- data = unitData;
- qmlData = nullptr;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- delete [] constants;
-#endif
- constants = nullptr;
- m_fileName.clear();
- m_finalUrlString.clear();
- if (!data)
- return;
-
- qmlData = qmlUnit ? qmlUnit : data->qmlUnit();
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- StaticValue *bigEndianConstants = new StaticValue[data->constantTableSize];
- const quint64_le *littleEndianConstants = data->constants();
- for (uint i = 0; i < data->constantTableSize; ++i)
- bigEndianConstants[i] = StaticValue::fromReturnedValue(littleEndianConstants[i]);
- constants = bigEndianConstants;
-#else
- constants = reinterpret_cast<const StaticValue*>(data->constants());
-#endif
-
- m_fileName = !fileName.isEmpty() ? fileName : stringAt(data->sourceFileIndex);
- m_finalUrlString = !finalUrlString.isEmpty() ? finalUrlString : stringAt(data->finalUrlIndex);
- }
-
- QString stringAt(int index) const
- {
- if (uint(index) >= data->stringTableSize)
- return dynamicStrings.at(index - data->stringTableSize);
- return data->stringAtInternal(index);
- }
-
- QString fileName() const { return m_fileName; }
- QString finalUrlString() const { return m_finalUrlString; }
-
- Heap::Module *module() const { return m_module; }
- void setModule(Heap::Module *module) { m_module = module; }
-
-private:
- QString m_fileName; // initialized from data->sourceFileIndex
- QString m_finalUrlString; // initialized from data->finalUrlIndex
-
- Heap::Module *m_module = nullptr;
-};
-
-class SaveableUnitPointer
-{
- Q_DISABLE_COPY_MOVE(SaveableUnitPointer)
-public:
- SaveableUnitPointer(const Unit *unit, quint32 temporaryFlags = Unit::StaticData) :
- unit(unit),
- temporaryFlags(temporaryFlags)
- {
- }
-
- ~SaveableUnitPointer() = default;
-
- template<typename Char>
- bool saveToDisk(const std::function<bool(const Char *, quint32)> &writer) const
- {
- auto cleanup = qScopeGuard([this]() { mutableFlags() ^= temporaryFlags; });
- mutableFlags() |= temporaryFlags;
- return writer(data<Char>(), size());
- }
-
- static bool writeDataToFile(const QString &outputFileName, const char *data, quint32 size,
- QString *errorString)
- {
-#if QT_CONFIG(temporaryfile)
- QSaveFile cacheFile(outputFileName);
- if (!cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate)
- || cacheFile.write(data, size) != size
- || !cacheFile.commit()) {
- *errorString = cacheFile.errorString();
- return false;
- }
-
- errorString->clear();
- return true;
-#else
- Q_UNUSED(outputFileName)
- *errorString = QStringLiteral("features.temporaryfile is disabled.");
- return false;
-#endif
- }
-
-private:
- const Unit *unit;
- quint32 temporaryFlags;
-
- quint32_le &mutableFlags() const
- {
- return const_cast<Unit *>(unit)->flags;
- }
-
- template<typename Char>
- const Char *data() const
- {
- Q_STATIC_ASSERT(sizeof(Char) == 1);
- const Char *dataPtr;
- memcpy(&dataPtr, &unit, sizeof(dataPtr));
- return dataPtr;
- }
-
- quint32 size() const
- {
- return unit->unitSize;
- }
-};
-
-
-} // CompiledData namespace
-} // QV4 namespace
-
-Q_DECLARE_TYPEINFO(QV4::CompiledData::JSClassMember, Q_PRIMITIVE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 22f393eaec..acc4b02e96 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -38,8 +38,8 @@
****************************************************************************/
#include <qv4compiler_p.h>
-#include <qv4compileddata_p.h>
#include <qv4codegen_p.h>
+#include <private/qv4compileddata_p.h>
#include <private/qv4staticvalue_p.h>
#include <private/qv4alloca_p.h>
#include <private/qqmljslexer_p.h>
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index f5884f6478..4f3c718175 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -53,9 +53,10 @@
#include <QtCore/qstring.h>
#include <QtCore/qhash.h>
#include <QtCore/qstringlist.h>
-#include <private/qv4global_p.h>
+#include <private/qv4compilerglobal_p.h>
#include <private/qqmljsastfwd_p.h>
#include <private/qv4compileddata_p.h>
+#include <private/qv4staticvalue_p.h>
QT_BEGIN_NAMESPACE
@@ -72,10 +73,12 @@ struct JSClassMember;
namespace Compiler {
+struct Context;
+struct Module;
struct Class;
struct TemplateObject;
-struct Q_QML_PRIVATE_EXPORT StringTableGenerator {
+struct Q_QMLCOMPILER_PRIVATE_EXPORT StringTableGenerator {
StringTableGenerator();
int registerString(const QString &str);
@@ -102,7 +105,7 @@ private:
bool frozen = false;
};
-struct Q_QML_PRIVATE_EXPORT JSUnitGenerator {
+struct Q_QMLCOMPILER_PRIVATE_EXPORT JSUnitGenerator {
static void generateUnitChecksum(CompiledData::Unit *unit);
struct MemberInfo {
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 1ae7c8c149..8c124ac409 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -50,7 +50,6 @@
// We mean it.
//
-#include "private/qv4global_p.h"
#include <private/qqmljsast_p.h>
#include <private/qv4compileddata_p.h>
#include <QtCore/QStringList>
@@ -62,8 +61,13 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+namespace Moth {
+class BytecodeGenerator;
+}
+
namespace Compiler {
+class Codegen;
struct ControlFlow;
enum class ContextType {
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
index 8ae618a6d4..5623473726 100644
--- a/src/qml/compiler/qv4compilercontrolflow_p.h
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -50,7 +50,6 @@
// We mean it.
//
-#include <private/qv4global_p.h>
#include <private/qv4codegen_p.h>
#include <private/qqmljsast_p.h>
#include <private/qv4bytecodegenerator_p.h>
diff --git a/src/qml/compiler/qv4stringtoarrayindex_p.h b/src/qml/compiler/qv4compilerglobal_p.h
index 61bd988d1e..3478074827 100644
--- a/src/qml/compiler/qv4stringtoarrayindex_p.h
+++ b/src/qml/compiler/qv4compilerglobal_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QV4STRINGTOARRAYINDEX_P_H
-#define QV4STRINGTOARRAYINDEX_P_H
+#ifndef QV4COMPILERGLOBAL_H
+#define QV4COMPILERGLOBAL_H
//
// W A R N I N G
@@ -51,46 +51,24 @@
// We mean it.
//
-#include <QtCore/private/qnumeric_p.h>
-#include <QtCore/qstring.h>
-#include <limits>
+#include <QtCore/qglobal.h>
+#include <QString>
+
+#include <private/qtqmlcompilerglobal_p.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
-inline uint charToUInt(const QChar *ch) { return ch->unicode(); }
-inline uint charToUInt(const char *ch) { return static_cast<unsigned char>(*ch); }
-
-template <typename T>
-uint stringToArrayIndex(const T *ch, const T *end)
-{
- uint i = charToUInt(ch) - '0';
- if (i > 9)
- return std::numeric_limits<uint>::max();
- ++ch;
- // reject "01", "001", ...
- if (i == 0 && ch != end)
- return std::numeric_limits<uint>::max();
-
- while (ch < end) {
- uint x = charToUInt(ch) - '0';
- if (x > 9)
- return std::numeric_limits<uint>::max();
- if (mul_overflow(i, uint(10), &i) || add_overflow(i, x, &i)) // i = i * 10 + x
- return std::numeric_limits<uint>::max();
- ++ch;
- }
- return i;
-}
-
-inline uint stringToArrayIndex(const QString &str)
-{
- return stringToArrayIndex(str.constData(), str.constData() + str.length());
-}
+enum class ObjectLiteralArgument {
+ Value,
+ Method,
+ Getter,
+ Setter
+};
} // namespace QV4
QT_END_NAMESPACE
-#endif // QV4STRINGTOARRAYINDEX_P_H
+#endif // QV4COMPILERGLOBAL_H
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 84d3ff5e31..f67db030a2 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -50,7 +50,7 @@
// We mean it.
//
-#include "private/qv4global_p.h"
+#include <private/qtqmlcompilerglobal_p.h>
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmljsengine_p.h>
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index ec81701160..c0dd696b8a 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -50,7 +50,7 @@
//
// We mean it.
//
-#include <private/qv4global_p.h>
+
#include <private/qv4staticvalue_p.h>
#include <private/qv4compileddata_p.h> // for CompiledData::CodeOffsetToLine used by the dumper
#include <qendian.h>
diff --git a/src/qml/compiler/qv4staticvalue_p.h b/src/qml/compiler/qv4staticvalue_p.h
deleted file mode 100644
index c6b4bdb158..0000000000
--- a/src/qml/compiler/qv4staticvalue_p.h
+++ /dev/null
@@ -1,548 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4STATICVALUE_P_H
-#define QV4STATICVALUE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQml/private/qtqmlglobal_p.h>
-#include <QtQml/private/qv4global_p.h>
-#include <QtCore/private/qnumeric_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-struct Double {
- quint64 d;
-
- Double(double dbl) {
- memcpy(&d, &dbl, sizeof(double));
- }
-
- int sign() const {
- return (d >> 63) ? -1 : 1;
- }
-
- bool isDenormal() const {
- return static_cast<int>((d << 1) >> 53) == 0;
- }
-
- int exponent() const {
- return static_cast<int>((d << 1) >> 53) - 1023;
- }
-
- quint64 significant() const {
- quint64 m = (d << 12) >> 12;
- if (!isDenormal())
- m |= (static_cast<quint64>(1) << 52);
- return m;
- }
-
- static int toInt32(double d) {
- int i = static_cast<int>(d);
- if (i == d)
- return i;
- return Double(d).toInt32();
- }
-
- int toInt32() {
- int e = exponent() - 52;
- if (e < 0) {
- if (e <= -53)
- return 0;
- return sign() * static_cast<int>(significant() >> -e);
- } else {
- if (e > 31)
- return 0;
- return sign() * (static_cast<int>(significant()) << e);
- }
- }
-};
-
-struct Q_QML_PRIVATE_EXPORT StaticValue
-{
- StaticValue() = default;
- constexpr StaticValue(quint64 val) : _val(val) {}
-
- StaticValue &operator=(ReturnedValue v)
- {
- _val = v;
- return *this;
- }
-
- template<typename Value>
- StaticValue &operator=(const Value &);
-
- template<typename Value>
- const Value &asValue() const;
-
- template<typename Value>
- Value &asValue();
-
- /*
- We use 8 bytes for a value and a different variant of NaN boxing. A Double
- NaN (actually -qNaN) is indicated by a number that has the top 13 bits set, and for a
- signalling NaN it is the top 14 bits. The other values are usually set to 0 by the
- processor, and are thus free for us to store other data. We keep pointers in there for
- managed objects, and encode the other types using the free space given to use by the unused
- bits for NaN values. This also works for pointers on 64 bit systems, as they all currently
- only have 48 bits of addressable memory. (Note: we do leave the lower 49 bits available for
- pointers.)
-
- We xor Doubles with (0xffff8000 << 32). That has the effect that no doubles will
- get encoded with bits 63-49 all set to 0. We then use bit 48 to distinguish between
- managed/undefined (0), or Null/Int/Bool/Empty (1). So, storing a 49 bit pointer will leave
- the top 15 bits 0, which is exactly the 'natural' representation of pointers. If bit 49 is
- set, bit 48 indicates Empty (0) or integer-convertible (1). Then the 3 bit below that are
- used to encode Null/Int/Bool.
-
- Undefined is encoded as a managed pointer with value 0. This is the same as a nullptr.
-
- Specific bit-sequences:
- 0 = always 0
- 1 = always 1
- x = stored value
- a,b,c,d = specific bit values, see notes
-
- 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 |
- 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 | JS Value
- ------------------------------------------------------------------------+--------------
- 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | Undefined
- 00000000 0000000x xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Managed (heap pointer)
- a0000000 0000bc00 00000000 00000000 00000000 00000000 00000000 00000000 | NaN/Inf
- dddddddd ddddddxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | double
- 00000000 00000010 00000000 00000000 00000000 00000000 00000000 00000000 | empty (non-sparse array hole)
- 00000000 00000010 10000000 00000000 00000000 00000000 00000000 00000000 | Null
- 00000000 00000011 00000000 00000000 00000000 00000000 00000000 0000000x | Bool
- 00000000 00000011 10000000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
-
- Notes:
- - a: xor-ed signbit, always 1 for NaN
- - bc, xor-ed values: 11 = inf, 10 = sNaN, 01 = qNaN, 00 = boxed value
- - d: xor-ed bits, where at least one bit is set, so: (val >> (64-14)) > 0
- - Undefined maps to C++ nullptr, so the "default" initialization is the same for both C++
- and JS
- - Managed has the left 15 bits set to 0, so: (val >> (64-15)) == 0
- - empty, Null, Bool, and Int have the left 14 bits set to 0, and bit 49 set to 1,
- so: (val >> (64-15)) == 1
- - Null, Bool, and Int have bit 48 set, indicating integer-convertible
- - xoring _val with NaNEncodeMask will convert to a double in "natural" representation, where
- any non double results in a NaN
- - on 32bit we can use the fact that addresses are 32bits wide, so the tag part (bits 32 to
- 63) are zero. No need to shift.
- */
-
- quint64 _val;
-
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 &rawValueRef() { return _val; }
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 rawValue() const { return _val; }
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setRawValue(quint64 raw) { _val = raw; }
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- static inline int valueOffset() { return 0; }
- static inline int tagOffset() { return 4; }
-#else // !Q_LITTLE_ENDIAN
- static inline int valueOffset() { return 4; }
- static inline int tagOffset() { return 0; }
-#endif
- static inline constexpr quint64 tagValue(quint32 tag, quint32 value) { return quint64(tag) << 32 | value; }
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTagValue(quint32 tag, quint32 value) { _val = quint64(tag) << 32 | value; }
- QML_NEARLY_ALWAYS_INLINE constexpr quint32 value() const { return _val & quint64(~quint32(0)); }
- QML_NEARLY_ALWAYS_INLINE constexpr quint32 tag() const { return _val >> 32; }
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTag(quint32 tag) { setTagValue(tag, value()); }
-
- QML_NEARLY_ALWAYS_INLINE constexpr int int_32() const
- {
- return int(value());
- }
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setInt_32(int i)
- {
- setTagValue(quint32(ValueTypeInternal::Integer), quint32(i));
- }
- QML_NEARLY_ALWAYS_INLINE uint uint_32() const { return value(); }
-
- QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setEmpty()
- {
- setTagValue(quint32(ValueTypeInternal::Empty), 0);
- }
-
- // ### Fix for 32 bit (easiest solution is to set highest bit to 1 for mananged/undefined/integercompatible
- // and use negative numbers here
- enum QuickType {
- QT_ManagedOrUndefined = 0,
- QT_ManagedOrUndefined1 = 1,
- QT_ManagedOrUndefined2 = 2,
- QT_ManagedOrUndefined3 = 3,
- QT_Empty = 4,
- QT_Null = 5,
- QT_Bool = 6,
- QT_Int = 7
- // all other values are doubles
- };
-
- enum Type {
- Undefined_Type = 0,
- Managed_Type = 1,
- Empty_Type = 4,
- Null_Type = 5,
- Boolean_Type = 6,
- Integer_Type = 7,
- Double_Type = 8
- };
-
- inline Type type() const {
- int t = quickType();
- if (t < QT_Empty)
- return _val ? Managed_Type : Undefined_Type;
- if (t > QT_Int)
- return Double_Type;
- return static_cast<Type>(t);
- }
-
- // Shared between 32-bit and 64-bit encoding
- enum {
- Tag_Shift = 32
- };
-
- // Used only by 64-bit encoding
- static const quint64 NaNEncodeMask = 0xfffc000000000000ull;
- enum {
- IsDouble_Shift = 64-14,
- IsManagedOrUndefined_Shift = 64-15,
- IsIntegerConvertible_Shift = 64-15,
- IsIntegerOrBool_Shift = 64-16,
- QuickType_Shift = 64 - 17,
- IsPositiveIntShift = 31
- };
-
- static const quint64 Immediate_Mask_64 = 0x00020000u; // bit 49
-
- enum class ValueTypeInternal_64 {
- Empty = Immediate_Mask_64 | 0,
- Null = Immediate_Mask_64 | 0x08000u,
- Boolean = Immediate_Mask_64 | 0x10000u,
- Integer = Immediate_Mask_64 | 0x18000u
- };
-
- // Used only by 32-bit encoding
- enum Masks {
- SilentNaNBit = 0x00040000,
- NotDouble_Mask = 0x7ffa0000,
- };
- static const quint64 Immediate_Mask_32 = NotDouble_Mask | 0x00020000u | SilentNaNBit;
-
- enum class ValueTypeInternal_32 {
- Empty = Immediate_Mask_32 | 0,
- Null = Immediate_Mask_32 | 0x08000u,
- Boolean = Immediate_Mask_32 | 0x10000u,
- Integer = Immediate_Mask_32 | 0x18000u
- };
-
- enum {
- Managed_Type_Internal = 0
- };
-
- using ValueTypeInternal = ValueTypeInternal_64;
-
- enum {
- NaN_Mask = 0x7ff80000,
- };
-
- inline quint64 quickType() const { return (_val >> QuickType_Shift); }
-
- // used internally in property
- inline bool isEmpty() const { return tag() == quint32(ValueTypeInternal::Empty); }
- inline bool isNull() const { return tag() == quint32(ValueTypeInternal::Null); }
- inline bool isBoolean() const { return tag() == quint32(ValueTypeInternal::Boolean); }
- inline bool isInteger() const { return tag() == quint32(ValueTypeInternal::Integer); }
- inline bool isNullOrUndefined() const { return isNull() || isUndefined(); }
- inline bool isNumber() const { return quickType() >= QT_Int; }
-
- inline bool isUndefined() const { return _val == 0; }
- inline bool isDouble() const { return (_val >> IsDouble_Shift); }
- inline bool isManaged() const
- {
-#if QT_POINTER_SIZE == 4
- return value() && tag() == Managed_Type_Internal;
-#else
- return _val && ((_val >> IsManagedOrUndefined_Shift) == 0);
-#endif
- }
- inline bool isManagedOrUndefined() const
- {
-#if QT_POINTER_SIZE == 4
- return tag() == Managed_Type_Internal;
-#else
- return ((_val >> IsManagedOrUndefined_Shift) == 0);
-#endif
- }
-
- inline bool isIntOrBool() const {
- return (_val >> IsIntegerOrBool_Shift) == 3;
- }
-
- inline bool integerCompatible() const {
- Q_ASSERT(!isEmpty());
- return (_val >> IsIntegerConvertible_Shift) == 1;
- }
-
- static inline bool integerCompatible(StaticValue a, StaticValue b) {
- return a.integerCompatible() && b.integerCompatible();
- }
-
- static inline bool bothDouble(StaticValue a, StaticValue b) {
- return a.isDouble() && b.isDouble();
- }
-
- inline bool isNaN() const
- {
- return (tag() & 0x7ffc0000 ) == 0x00040000;
- }
-
- inline bool isPositiveInt() const {
-#if QT_POINTER_SIZE == 4
- return isInteger() && int_32() >= 0;
-#else
- return (_val >> IsPositiveIntShift) == (quint64(ValueTypeInternal::Integer) << 1);
-#endif
- }
-
- QML_NEARLY_ALWAYS_INLINE double doubleValue() const {
- Q_ASSERT(isDouble());
- double d;
- StaticValue v = *this;
- v._val ^= NaNEncodeMask;
- memcpy(&d, &v._val, 8);
- return d;
- }
-
- QML_NEARLY_ALWAYS_INLINE void setDouble(double d) {
- if (qt_is_nan(d))
- d = qt_qnan();
- memcpy(&_val, &d, 8);
- _val ^= NaNEncodeMask;
- Q_ASSERT(isDouble());
- }
-
- inline bool isInt32() {
- if (tag() == quint32(ValueTypeInternal::Integer))
- return true;
- if (isDouble()) {
- double d = doubleValue();
- if (isInt32(d)) {
- setInt_32(int(d));
- return true;
- }
- }
- return false;
- }
-
- QML_NEARLY_ALWAYS_INLINE static bool isInt32(double d) {
- int i = int(d);
- return (i == d && !(d == 0 && std::signbit(d)));
- }
-
- double asDouble() const {
- if (tag() == quint32(ValueTypeInternal::Integer))
- return int_32();
- return doubleValue();
- }
-
- bool booleanValue() const {
- return int_32();
- }
-
- int integerValue() const {
- return int_32();
- }
-
- inline bool tryIntegerConversion() {
- bool b = integerCompatible();
- if (b)
- setTagValue(quint32(ValueTypeInternal::Integer), value());
- return b;
- }
-
- bool toBoolean() const {
- if (integerCompatible())
- return static_cast<bool>(int_32());
-
- if (isManagedOrUndefined())
- return false;
-
- // double
- const double d = doubleValue();
- return d && !std::isnan(d);
- }
-
- inline int toInt32() const
- {
- switch (type()) {
- case Null_Type:
- case Boolean_Type:
- case Integer_Type:
- return int_32();
- case Double_Type:
- return Double::toInt32(doubleValue());
- case Empty_Type:
- case Undefined_Type:
- case Managed_Type:
- break;
- }
- return Double::toInt32(std::numeric_limits<double>::quiet_NaN());
- }
-
- ReturnedValue *data_ptr() { return &_val; }
- constexpr ReturnedValue asReturnedValue() const { return _val; }
- constexpr static StaticValue fromReturnedValue(ReturnedValue val) { return {val}; }
-
- inline static constexpr StaticValue emptyValue() { return { tagValue(quint32(ValueTypeInternal::Empty), 0) }; }
- static inline constexpr StaticValue fromBoolean(bool b) { return { tagValue(quint32(ValueTypeInternal::Boolean), b) }; }
- static inline constexpr StaticValue fromInt32(int i) { return { tagValue(quint32(ValueTypeInternal::Integer), quint32(i)) }; }
- inline static constexpr StaticValue undefinedValue() { return { 0 }; }
- static inline constexpr StaticValue nullValue() { return { tagValue(quint32(ValueTypeInternal::Null), 0) }; }
-
- static inline StaticValue fromDouble(double d)
- {
- StaticValue v;
- v.setDouble(d);
- return v;
- }
-
- static inline StaticValue fromUInt32(uint i)
- {
- StaticValue v;
- if (i < uint(std::numeric_limits<int>::max())) {
- v.setTagValue(quint32(ValueTypeInternal::Integer), i);
- } else {
- v.setDouble(i);
- }
- return v;
- }
-
- static double toInteger(double d)
- {
- if (std::isnan(d))
- return +0;
- if (!d || std::isinf(d))
- return d;
- return d >= 0 ? std::floor(d) : std::ceil(d);
- }
-
- static int toInt32(double d)
- {
- return Double::toInt32(d);
- }
-
- static unsigned int toUInt32(double d)
- {
- return static_cast<uint>(toInt32(d));
- }
-};
-Q_STATIC_ASSERT(std::is_trivial<StaticValue>::value);
-
-struct Encode {
- static constexpr ReturnedValue undefined() {
- return StaticValue::undefinedValue().asReturnedValue();
- }
- static constexpr ReturnedValue null() {
- return StaticValue::nullValue().asReturnedValue();
- }
-
- explicit constexpr Encode(bool b)
- : val(StaticValue::fromBoolean(b).asReturnedValue())
- {
- }
- explicit Encode(double d) {
- val = StaticValue::fromDouble(d).asReturnedValue();
- }
- explicit constexpr Encode(int i)
- : val(StaticValue::fromInt32(i).asReturnedValue())
- {
- }
- explicit Encode(uint i) {
- val = StaticValue::fromUInt32(i).asReturnedValue();
- }
- explicit constexpr Encode(ReturnedValue v)
- : val(v)
- {
- }
- constexpr Encode(StaticValue v)
- : val(v.asReturnedValue())
- {
- }
-
- template<typename HeapBase>
- explicit Encode(HeapBase *o);
-
- explicit Encode(StaticValue *o) {
- Q_ASSERT(o);
- val = o->asReturnedValue();
- }
-
- static ReturnedValue smallestNumber(double d) {
- if (StaticValue::isInt32(d))
- return Encode(static_cast<int>(d));
- else
- return Encode(d);
- }
-
- constexpr operator ReturnedValue() const {
- return val;
- }
- quint64 val;
-private:
- explicit Encode(void *);
-};
-
-}
-
-QT_END_NAMESPACE
-
-#endif // QV4STATICVALUE_P_H