aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp16
-rw-r--r--src/qml/compiler/qv4compileddata_p.h15
-rw-r--r--src/qml/compiler/qv4compiler.cpp6
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h3
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp13
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h11
6 files changed, 41 insertions, 23 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index 9feafb8bd4..dfdb71b253 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -40,6 +40,7 @@
#include <private/qv4bytecodegenerator_p.h>
#include <private/qv4compilercontext_p.h>
#include <private/qqmljsastfwd_p.h>
+#include <private/qv4compileddata_p.h>
QT_USE_NAMESPACE
using namespace QV4;
@@ -161,15 +162,16 @@ void BytecodeGenerator::finalize(Compiler::Context *context)
// collect content and line numbers
QByteArray code;
- QVector<int> lineNumbers;
- currentLine = startLine;
+ QVector<CompiledData::CodeOffsetToLine> lineNumbers;
+ currentLine = -1;
+ Q_UNUSED(startLine);
for (const auto &i : qAsConst(instructions)) {
if (i.line != currentLine) {
- Q_ASSERT(i.line > currentLine);
- while (currentLine < i.line) {
- lineNumbers.append(code.size());
- ++currentLine;
- }
+ currentLine = i.line;
+ CompiledData::CodeOffsetToLine entry;
+ entry.codeOffset = code.size();
+ entry.line = currentLine;
+ lineNumbers.append(entry);
}
code.append(i.packed, i.size);
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 445c3c7091..6c8e2bc121 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -71,7 +71,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x13
+#define QV4_DATA_STRUCTURE_VERSION 0x14
class QIODevice;
class QQmlPropertyCache;
@@ -194,6 +194,11 @@ struct String
}
};
+struct CodeOffsetToLine {
+ quint32_le codeOffset;
+ quint32_le line;
+};
+
// 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
@@ -242,7 +247,7 @@ struct Function
const quint32_le *formalsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + formalsOffset); }
const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
- const quint32_le *lineNumberTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + lineNumberOffset); }
+ const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset); }
const quint32_le *qmlIdObjectDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingIdObjectsOffset); }
const quint32_le *qmlContextPropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingContextPropertiesOffset); }
const quint32_le *qmlScopePropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingScopePropertiesOffset); }
@@ -255,9 +260,9 @@ struct Function
inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; }
static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies) {
- int trailingData = nFormals + nLocals + nLines + nInnerfunctions + nIdObjectDependencies +
- 2 * nPropertyDependencies;
- return align(align(sizeof(Function)) + size_t(trailingData) * sizeof(quint32));
+ int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies +
+ 2 * nPropertyDependencies)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine);
+ return align(align(sizeof(Function)) + size_t(trailingData));
}
static size_t align(size_t a) {
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index acfd5c56e7..aaa06efa8c 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -318,7 +318,7 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
function->nLineNumbers = irFunction->lineNumberMapping.size();
function->lineNumberOffset = currentOffset;
- currentOffset += function->nLineNumbers * sizeof(quint32);
+ currentOffset += function->nLineNumbers * sizeof(CompiledData::CodeOffsetToLine);
function->nInnerFunctions = irFunction->nestedContexts.size();
@@ -363,9 +363,7 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
locals[i] = getStringId(irFunction->locals.at(i));
// write line numbers
- quint32 *lineNumbers = (quint32 *)(f + function->lineNumberOffset);
- for (int i = 0; i < irFunction->lineNumberMapping.size(); ++i)
- lineNumbers[i] = irFunction->lineNumberMapping.at(i);
+ memcpy(f + function->lineNumberOffset, irFunction->lineNumberMapping.constData(), irFunction->lineNumberMapping.size()*sizeof(CompiledData::CodeOffsetToLine));
// write QML dependencies
quint32_le *writtenDeps = (quint32_le *)(f + function->dependingIdObjectsOffset);
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 796f313b5c..b796a5f149 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -52,6 +52,7 @@
#include "private/qv4global_p.h"
#include <private/qqmljsast_p.h>
+#include <private/qv4compileddata_p.h>
#include <QtCore/QStringList>
#include <QtCore/QDateTime>
#include <QtCore/QStack>
@@ -133,7 +134,7 @@ struct Context {
ControlFlow *controlFlow = 0;
QByteArray code;
- QVector<int> lineNumberMapping;
+ QVector<CompiledData::CodeOffsetToLine> lineNumberMapping;
int maxNumberOfArguments = 0;
bool hasDirectEval = false;
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 056e8d6624..c51f604500 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qv4instr_moth_p.h"
+#include <private/qv4compileddata_p.h>
using namespace QV4;
using namespace QV4::Moth;
@@ -117,17 +118,21 @@ void dumpConstantTable(const Value *constants, uint count)
<< toString(constants[i].asReturnedValue()).toUtf8().constData() << "\n";
}
-void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int startLine, const QVector<int> &lineNumberMapping)
+void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*startLine*/, const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping)
{
-
MOTH_JUMP_TABLE;
+ auto findLine = [](const CompiledData::CodeOffsetToLine &entry, uint offset) {
+ return entry.codeOffset < offset;
+ };
+
int lastLine = -1;
const char *start = code;
const char *end = code + len;
while (code < end) {
- int line = startLine + ((code == start) ? 0 : lineNumberMapping.lastIndexOf(static_cast<uint>(code - start)) + 1);
- if (line > lastLine)
+ const CompiledData::CodeOffsetToLine *codeToLine = std::lower_bound(lineNumberMapping.constBegin(), lineNumberMapping.constEnd(), static_cast<uint>(code - start) + 1, findLine) - 1;
+ int line = codeToLine->line;
+ if (line != lastLine)
lastLine = line;
else
line = -1;
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index dc262f5a37..cc26c88155 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -414,6 +414,11 @@ QT_BEGIN_NAMESPACE
#endif
namespace QV4 {
+
+namespace CompiledData {
+struct CodeOffsetToLine;
+}
+
namespace Moth {
class StackSlot {
@@ -467,8 +472,10 @@ inline bool operator!=(const StackSlot &l, const StackSlot &r) { return l.stackS
// When making changes to the instructions, make sure to bump QV4_DATA_STRUCTURE_VERSION in qv4compileddata_p.h
void dumpConstantTable(const Value *constants, uint count);
-void dumpBytecode(const char *bytecode, int len, int nLocals, int nFormals, int startLine = 1, const QVector<int> &lineNumberMapping = QVector<int>());
-inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine = 1, const QVector<int> &lineNumberMapping = QVector<int>()) {
+void dumpBytecode(const char *bytecode, int len, int nLocals, int nFormals, int startLine = 1,
+ const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>());
+inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine = 1,
+ const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>()) {
dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals, startLine, lineNumberMapping);
}