aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-21 10:59:53 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-08-25 12:05:59 +0000
commit4e0174a88e66b9d9471c98eeb7d8be6209ba5c98 (patch)
tree573aac0c41d77fab6dfe37d4d75e0446165d78f0
parent3c201dd0d95020c4cb4c8ceaf779673d411664e7 (diff)
Move line number information into a side table
Don't emit any Line instructions anymore, and instead store the info in a side table in the compiled data, where it can be looked up on demand. Change-Id: Idcaf3bf4ee4129fd62f9e717bf1277dc6a34fe19 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp6
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp20
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h10
-rw-r--r--src/qml/compiler/qv4codegen.cpp7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h9
-rw-r--r--src/qml/compiler/qv4compiler.cpp11
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h1
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp24
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h13
-rw-r--r--src/qml/jsruntime/qv4engine.cpp17
-rw-r--r--src/qml/jsruntime/qv4engine_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp41
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp2
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp16
19 files changed, 128 insertions, 71 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index c95d4ea99f..4ef377922b 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -158,7 +158,7 @@ QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;
state.fileName = getFunction()->sourceFile();
- state.lineNumber = engine()->currentStackFrame->line;
+ state.lineNumber = engine()->currentStackFrame->lineNumber();
return state;
}
@@ -203,7 +203,7 @@ void QV4Debugger::maybeBreakAtInstruction()
pauseAndWait(PauseRequest);
} else if (m_haveBreakPoints) {
if (QV4::Function *f = getFunction()) {
- const int lineNumber = engine()->currentStackFrame->line;
+ const int lineNumber = engine()->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
pauseAndWait(BreakPointHit);
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index 316fd87dd4..2a46dc60a6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -84,11 +84,11 @@ void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseR
break;
body.insert(QStringLiteral("invocationText"), frame->function());
- body.insert(QStringLiteral("sourceLine"), frame->line - 1);
- if (frame->column > 0)
- body.insert(QStringLiteral("sourceColumn"), frame->column);
+ body.insert(QStringLiteral("sourceLine"), frame->lineNumber() - 1);
+// if (frame->column > 0)
+// body.insert(QStringLiteral("sourceColumn"), frame->column);
QJsonArray breakPoints;
- foreach (int breakPointId, breakPointIds(frame->source(), frame->line))
+ foreach (int breakPointId, breakPointIds(frame->source(), frame->lineNumber()))
breakPoints.push_back(breakPointId);
body.insert(QStringLiteral("breakpoints"), breakPoints);
script.insert(QStringLiteral("name"), frame->source());
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index c879c77fcd..5015c39c8e 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -344,7 +344,7 @@ void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &a
frame.insert(QStringLiteral("function"), functionName->toQString());
frame.insert(QStringLiteral("file"), function->sourceFile());
- int line = f->line;
+ int line = f->lineNumber();
frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
frameArray.push_back(frame);
@@ -607,7 +607,7 @@ void NativeDebugger::maybeBreakAtInstruction()
if (m_service->m_breakHandler->m_haveBreakPoints) {
if (QV4::Function *function = getFunction()) {
- const int lineNumber = m_engine->currentStackFrame->line;
+ const int lineNumber = m_engine->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(function, lineNumber))
pauseAndWait();
}
@@ -668,7 +668,7 @@ void NativeDebugger::pauseAndWait()
if (QV4::CppStackFrame *frame = m_engine->currentStackFrame) {
QV4::Function *function = frame->v4Function;
event.insert(QStringLiteral("file"), function->sourceFile());
- int line = frame->line;
+ int line = frame->lineNumber();
event.insert(QStringLiteral("line"), (line < 0 ? -line : line));
}
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index c9b7c4ae7e..cae984a253 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <private/qv4bytecodegenerator_p.h>
+#include <private/qv4compilercontext_p.h>
#include <private/qqmljsastfwd_p.h>
QT_USE_NAMESPACE
@@ -46,12 +47,7 @@ using namespace Moth;
void BytecodeGenerator::setLocation(const QQmlJS::AST::SourceLocation &loc)
{
- if (static_cast<int>(loc.startLine) == currentLine)
- return;
currentLine = static_cast<int>(loc.startLine);
- Instruction::Line line;
- line.lineNumber = currentLine;
- addInstruction(line); //### put line numbers in a side-table, not in the instruction stream
}
int BytecodeGenerator::newRegister()
@@ -71,14 +67,23 @@ int BytecodeGenerator::newRegisterArray(int n)
return t;
}
-QByteArray BytecodeGenerator::finalize()
+void BytecodeGenerator::finalize(Compiler::Context *context)
{
QByteArray code;
// content
QVector<int> instructionOffsets;
+ QVector<int> lineNumbers;
+ currentLine = startLine;
instructionOffsets.reserve(instructions.size());
for (const auto &i : qAsConst(instructions)) {
+ if (i.line != currentLine) {
+ Q_ASSERT(i.line > currentLine);
+ while (currentLine < i.line) {
+ lineNumbers.append(code.size());
+ ++currentLine;
+ }
+ }
instructionOffsets.append(code.size());
code.append(reinterpret_cast<const char *>(&i.instr), i.size);
}
@@ -97,5 +102,6 @@ QByteArray BytecodeGenerator::finalize()
memcpy(c, &linkedInstructionOffset, sizeof(ptrdiff_t));
}
- return code;
+ context->code = code;
+ context->lineNumberMapping = lineNumbers;
}
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index f53a720d2c..5ab8c880f3 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -65,6 +65,8 @@ namespace Moth {
class BytecodeGenerator {
public:
+ BytecodeGenerator(int line)
+ : startLine(line) {}
struct Label {
enum LinkMode {
@@ -221,7 +223,7 @@ public:
int newRegisterArray(int n);
int registerCount() const { return regCount; }
- QByteArray finalize();
+ void finalize(Compiler::Context *context);
template<int InstrT>
Jump addJumpInstruction(const InstrData<InstrT> &data)
@@ -239,7 +241,7 @@ private:
int addInstructionHelper(uint size, const Instr &i) {
int pos = instructions.size();
- instructions.append({size, i});
+ instructions.append({size, currentLine, i});
return pos;
}
@@ -251,6 +253,7 @@ private:
struct I {
uint size;
+ int line;
Instr instr;
};
@@ -262,7 +265,8 @@ private:
public:
int currentReg = 0;
private:
- int currentLine = -1;
+ int startLine = 0;
+ int currentLine = 0;
};
}
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 273856e541..7e8a823939 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1932,7 +1932,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
// ### still needed?
_context->maxNumberOfArguments = qMax(_context->maxNumberOfArguments, (int)QV4::Global::ReservedArgumentCount);
- BytecodeGenerator bytecode;
+ BytecodeGenerator bytecode(_context->line);
BytecodeGenerator *savedBytecodeGenerator;
savedBytecodeGenerator = bytecodeGenerator;
bytecodeGenerator = &bytecode;
@@ -2025,13 +2025,14 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator->addInstruction(Instruction::Ret());
}
- _context->code = bytecodeGenerator->finalize();
+ bytecodeGenerator->finalize(_context);
_context->registerCount = bytecodeGenerator->registerCount();
static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
if (showCode) {
qDebug() << "=== Bytecode for" << _context->name << "strict mode" << _context->isStrict
<< "register count" << _context->registerCount;
- QV4::Moth::dumpBytecode(_context->code, _context->locals.size(), _context->arguments.size());
+ QV4::Moth::dumpBytecode(_context->code, _context->locals.size(), _context->arguments.size(),
+ _context->line, _context->lineNumberMapping);
qDebug();
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 91ef2eac20..445c3c7091 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 0x12
+#define QV4_DATA_STRUCTURE_VERSION 0x13
class QIODevice;
class QQmlPropertyCache;
@@ -217,6 +217,8 @@ struct Function
quint32_le formalsOffset;
quint32_le nLocals;
quint32_le localsOffset;
+ quint32_le nLineNumbers;
+ quint32_le lineNumberOffset;
quint32_le nInnerFunctions;
quint32_le nRegisters;
Location location;
@@ -240,6 +242,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 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); }
@@ -251,8 +254,8 @@ struct Function
inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; }
- static int calculateSize(int nFormals, int nLocals, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies) {
- int trailingData = nFormals + nLocals + nInnerfunctions + nIdObjectDependencies +
+ 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));
}
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 84deb076b3..acfd5c56e7 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -316,6 +316,10 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
function->localsOffset = currentOffset;
currentOffset += function->nLocals * sizeof(quint32);
+ function->nLineNumbers = irFunction->lineNumberMapping.size();
+ function->lineNumberOffset = currentOffset;
+ currentOffset += function->nLineNumbers * sizeof(quint32);
+
function->nInnerFunctions = irFunction->nestedContexts.size();
function->nRegisters = irFunction->registerCount;
@@ -358,6 +362,11 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
for (int i = 0; i < irFunction->locals.size(); ++i)
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);
+
// write QML dependencies
quint32_le *writtenDeps = (quint32_le *)(f + function->dependingIdObjectsOffset);
for (int id : irFunction->idObjectDependencies) {
@@ -428,7 +437,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
const int qmlIdDepsCount = f->idObjectDependencies.count();
const int qmlPropertyDepsCount = f->scopeObjectPropertyDependencies.count() + f->contextObjectPropertyDependencies.count();
- nextOffset += QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->nestedContexts.size(), qmlIdDepsCount, qmlPropertyDepsCount);
+ nextOffset += QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(), qmlIdDepsCount, qmlPropertyDepsCount);
}
if (option == GenerateWithStringTable) {
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 0a204d8c24..796f313b5c 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -133,6 +133,7 @@ struct Context {
ControlFlow *controlFlow = 0;
QByteArray code;
+ QVector<int> lineNumberMapping;
int maxNumberOfArguments = 0;
bool hasDirectEval = false;
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 9101537236..523fe88c02 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -59,6 +59,12 @@ static QByteArray alignedNumber(int n) {
return number;
}
+static QByteArray alignedLineNumber(int line) {
+ if (line > 0)
+ return alignedNumber(static_cast<int>(line));
+ return QByteArray(" ");
+}
+
static QString toString(QV4::ReturnedValue v)
{
#ifdef V4_BOOTSTRAP
@@ -91,7 +97,7 @@ size_t absoluteInstructionOffset(const char *codeStart, const T &instr)
QDebug d = qDebug(); \
d.noquote(); \
d.nospace(); \
- d << alignedNumber(int(code - start)).constData() << ": " << #I << " "; \
+ d << alignedLineNumber(line) << alignedNumber(int(code - start)).constData() << ": " << #I << " "; \
code += InstrMeta<int(Instr::I)>::Size; \
#define MOTH_END_INSTR(I) } break;
@@ -109,12 +115,18 @@ 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)
+void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int startLine, const QVector<int> &lineNumberMapping)
{
+ int lastLine = -1;
const char *start = code;
const char *end = code + len;
while (code < end) {
const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
+ int line = startLine + ((code == start) ? 0 : lineNumberMapping.lastIndexOf(static_cast<uint>(code - start)) + 1);
+ if (line > lastLine)
+ lastLine = line;
+ else
+ line = -1;
switch (genericInstr->common.instructionType) {
MOTH_BEGIN_INSTR(LoadReg)
@@ -516,14 +528,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals)
MOTH_BEGIN_INSTR(Ret)
MOTH_END_INSTR(Ret)
- #ifndef QT_NO_QML_DEBUGGER
+#ifndef QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(Debug)
MOTH_END_INSTR(Debug)
-
- MOTH_BEGIN_INSTR(Line)
- d << instr.lineNumber;
- MOTH_END_INSTR(Line)
- #endif // QT_NO_QML_DEBUGGER
+#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadQmlContext)
d << instr.result.dump(nFormals);
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 2ce0ff7b22..588ee7c110 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -64,7 +64,6 @@ QT_BEGIN_NAMESPACE
#define MOTH_DEBUG_INSTR(F)
#else
#define MOTH_DEBUG_INSTR(F) \
- F(Line, line) \
F(Debug, debug)
#endif
@@ -236,9 +235,9 @@ 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);
-inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals) {
- dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals);
+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>()) {
+ dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals, startLine, lineNumberMapping);
}
union Instr
@@ -256,13 +255,8 @@ union Instr
};
#ifndef QT_NO_QML_DEBUGGING
- struct instr_line {
- MOTH_INSTR_HEADER
- qint32 lineNumber;
- };
struct instr_debug {
MOTH_INSTR_HEADER
- qint32 lineNumber;
};
#endif // QT_NO_QML_DEBUGGING
@@ -714,7 +708,6 @@ union Instr
instr_common common;
instr_ret ret;
- instr_line line;
instr_debug debug;
instr_loadConst loadConst;
instr_loadZero loadZero;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index f5effc8c3b..ce21e0f7e5 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -794,6 +794,19 @@ QString CppStackFrame::function() const
return v4Function->name()->toQString();
}
+int CppStackFrame::lineNumber() const
+{
+ const QV4::CompiledData::Function *cf = v4Function->compiledFunction;
+ uint offset = static_cast<uint>(instructionPointer - v4Function->codeData - 1); // -1 because the instructionPointer points to the next instruction
+ const quint32_le *lineNumbers = cf->lineNumberTable();
+ int nLineNumbers = cf->nLineNumbers;
+ for (int i = 0; i < nLineNumbers; ++i) {
+ if (offset <= lineNumbers[i])
+ return cf->location.line + i;
+ }
+ return cf->location.line + nLineNumbers;
+}
+
ReturnedValue CppStackFrame::thisObject() const {
return jsFrame->stack[-(int)v4Function->nFormals - 1].asReturnedValue();
}
@@ -809,8 +822,8 @@ StackTrace ExecutionEngine::stackTrace(int frameLimit) const
QV4::StackFrame frame;
frame.source = f->source();
frame.function = f->function();
- frame.line = f->line;
- frame.column = f->column;
+ frame.line = f->lineNumber();
+ frame.column = -1;
stack.append(frame);
--frameLimit;
f = f->parent;
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 3c3e6e048f..4cee69ed33 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -107,14 +107,14 @@ struct Q_QML_EXPORT CppStackFrame {
CppStackFrame *parent;
Function *v4Function;
JSStackFrame *jsFrame;
- int line = -1;
- int column = -1;
+ const uchar *instructionPointer;
QString source() const;
QString function() const;
inline QV4::ExecutionContext *context() const {
return static_cast<ExecutionContext *>(&jsFrame->context);
}
+ int lineNumber() const;
inline QV4::Heap::CallContext *callContext() const {
Heap::ExecutionContext *ctx = static_cast<ExecutionContext &>(jsFrame->context).d();\
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 13cad8c081..2d791092dd 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -472,7 +472,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
qCInfo(lcBindingRemoval,
"Overwriting binding on %s::%s at %s:%d that was initially bound at %s",
object->metaObject()->className(), qPrintable(property->name(object)),
- qPrintable(stackFrame->source()), stackFrame->line,
+ qPrintable(stackFrame->source()), stackFrame->lineNumber(),
qPrintable(qmlBinding->expressionIdentifier()));
}
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index d3d8c1c291..23dfd3fc89 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -60,7 +60,7 @@
using namespace QV4;
Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit)
- : line(0), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
+ : line(1), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
, compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true)
{
if (qml)
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 10043be917..54a32e0747 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -68,7 +68,7 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
QV4::CppStackFrame *stackFrame = v4->currentStackFrame;
- retn.setLine(stackFrame->line);
+ retn.setLine(stackFrame->lineNumber());
retn.setUrl(QUrl(stackFrame->source()));
QQmlEnginePrivate::warning(engine, retn);
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 6aad96c0c8..c7beed7b22 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -242,7 +242,7 @@ Q_NEVER_INLINE static void qt_v4CheckForBreak(QV4::CppStackFrame *frame)
if (!qt_v4IsStepping && !qt_v4Breakpoints.size())
return;
- const int lineNumber = frame->line;
+ const int lineNumber = frame->lineNumber();
QV4::Function *function = frame->v4Function;
QString engineName = function->sourceFile();
@@ -273,10 +273,8 @@ Q_NEVER_INLINE static void qt_v4CheckForBreak(QV4::CppStackFrame *frame)
}
}
-Q_NEVER_INLINE static void debug_slowPath(const QV4::Moth::Instr::instr_debug &instr,
- QV4::ExecutionEngine *engine)
+Q_NEVER_INLINE static void debug_slowPath(QV4::ExecutionEngine *engine)
{
- engine->currentStackFrame->line = instr.lineNumber;
QV4::Debugging::Debugger *debugger = engine->debugger();
if (debugger && debugger->pauseAtNextOpportunity())
debugger->maybeBreakAtInstruction();
@@ -515,6 +513,7 @@ static bool compareEqualInt(Value lhs, int rhs)
}
}
+#define STORE_IP() frame.instructionPointer = code
QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callData, Heap::ExecutionContext *context, QV4::Function *function)
{
@@ -539,6 +538,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
CppStackFrame frame;
frame.parent = engine->currentStackFrame;
frame.v4Function = function;
+ frame.instructionPointer = function->codeData;
engine->currentStackFrame = &frame;
QV4::Value *stack = nullptr;
@@ -631,6 +631,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
+ STORE_IP();
STORE_ACCUMULATOR(Runtime::method_loadName(engine, instr.name));
MOTH_END_INSTR(LoadName)
@@ -640,54 +641,65 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(LoadGlobalLookup)
MOTH_BEGIN_INSTR(StoreNameStrict)
+ STORE_IP();
Runtime::method_storeNameStrict(engine, instr.name, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreNameSloppy)
MOTH_BEGIN_INSTR(StoreNameSloppy)
+ STORE_IP();
Runtime::method_storeNameSloppy(engine, instr.name, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreNameSloppy)
MOTH_BEGIN_INSTR(LoadElement)
+ STORE_IP();
STORE_ACCUMULATOR(Runtime::method_loadElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index)));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementA)
+ STORE_IP();
STORE_ACCUMULATOR(Runtime::method_loadElement(engine, STACK_VALUE(instr.base), accumulator));
MOTH_END_INSTR(LoadElementA)
MOTH_BEGIN_INSTR(StoreElement)
+ STORE_IP();
if (!Runtime::method_storeElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index), accumulator) && function->isStrict())
engine->throwTypeError();
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
+ STORE_IP();
STORE_ACCUMULATOR(Runtime::method_loadProperty(engine, STACK_VALUE(instr.base), instr.name));
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(LoadPropertyA)
+ STORE_IP();
STORE_ACCUMULATOR(Runtime::method_loadProperty(engine, accumulator, instr.name));
MOTH_END_INSTR(LoadPropertyA)
MOTH_BEGIN_INSTR(GetLookup)
+ STORE_IP();
QV4::Lookup *l = function->compilationUnit->runtimeLookups + instr.index;
STORE_ACCUMULATOR(l->getter(l, engine, STACK_VALUE(instr.base)));
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(GetLookupA)
+ STORE_IP();
QV4::Lookup *l = function->compilationUnit->runtimeLookups + instr.index;
STORE_ACCUMULATOR(l->getter(l, engine, accumulator));
MOTH_END_INSTR(GetLookupA)
MOTH_BEGIN_INSTR(StoreProperty)
+ STORE_IP();
if (!Runtime::method_storeProperty(engine, STACK_VALUE(instr.base), instr.name, accumulator) && function->isStrict())
engine->throwTypeError();
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
+ STORE_IP();
QV4::Lookup *l = function->compilationUnit->runtimeLookups + instr.index;
if (!l->setter(l, engine, STACK_VALUE(instr.base), accumulator) && function->isStrict())
engine->throwTypeError();
@@ -717,39 +729,46 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(LoadIdObject)
MOTH_BEGIN_INSTR(CallValue)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
STORE_ACCUMULATOR(Runtime::method_callValue(engine, accumulator, callData));
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
callData->thisObject = STACK_VALUE(instr.base);
STORE_ACCUMULATOR(Runtime::method_callProperty(engine, instr.name, callData));
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
callData->thisObject = STACK_VALUE(instr.base);
STORE_ACCUMULATOR(Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData));
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
callData->thisObject = STACK_VALUE(instr.base);
STORE_ACCUMULATOR(Runtime::method_callElement(engine, STACK_VALUE(instr.index), callData));
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallName)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
STORE_ACCUMULATOR(Runtime::method_callName(engine, instr.name, callData));
MOTH_END_INSTR(CallName)
MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
STORE_ACCUMULATOR(Runtime::method_callPossiblyDirectEval(engine, callData));
MOTH_END_INSTR(CallPossiblyDirectEval)
MOTH_BEGIN_INSTR(CallGlobalLookup)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
STORE_ACCUMULATOR(Runtime::method_callGlobalLookup(engine, instr.index, callData));
MOTH_END_INSTR(CallGlobalLookup)
@@ -760,6 +779,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(SetExceptionHandler)
MOTH_BEGIN_INSTR(ThrowException)
+ STORE_IP();
Runtime::method_throwException(engine, accumulator);
goto catchException;
MOTH_END_INSTR(ThrowException)
@@ -783,6 +803,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(PushCatchContext)
MOTH_BEGIN_INSTR(PushWithContext)
+ STORE_IP();
accumulator = accumulator.toObject(engine);
CHECK_EXCEPTION;
STACK_VALUE(instr.reg) = Runtime::method_pushWithContext(accumulator, static_cast<QV4::NoThrowEngine*>(engine));
@@ -803,6 +824,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_BEGIN_INSTR(DeleteMember)
if (!Runtime::method_deleteMember(engine, STACK_VALUE(instr.base), instr.member)) {
if (function->isStrict()) {
+ STORE_IP();
engine->throwTypeError();
goto catchException;
}
@@ -815,6 +837,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_BEGIN_INSTR(DeleteSubscript)
if (!Runtime::method_deleteElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index))) {
if (function->isStrict()) {
+ STORE_IP();
engine->throwTypeError();
goto catchException;
}
@@ -827,6 +850,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_BEGIN_INSTR(DeleteName)
if (!Runtime::method_deleteName(engine, instr.name)) {
if (function->isStrict()) {
+ STORE_IP();
QString name = function->compilationUnit->runtimeStrings[instr.name]->toQString();
engine->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name));
goto catchException;
@@ -880,6 +904,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
MOTH_END_INSTR(ConvertThisToObject)
MOTH_BEGIN_INSTR(Construct)
+ STORE_IP();
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot());
STORE_ACCUMULATOR(Runtime::method_construct(engine, STACK_VALUE(instr.func), callData));
MOTH_END_INSTR(Construct)
@@ -1171,14 +1196,8 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
#ifndef QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(Debug)
- debug_slowPath(instr, engine);
+ debug_slowPath(engine);
MOTH_END_INSTR(Debug)
-
- MOTH_BEGIN_INSTR(Line)
- frame.line = instr.lineNumber;
- if (Q_UNLIKELY(qt_v4IsDebugging))
- qt_v4CheckForBreak(&frame);
- MOTH_END_INSTR(Line)
#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadQmlContext)
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 532c4b1454..ebca199ee1 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -479,7 +479,7 @@ bool QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
referenceObject->metaObject()->className(), referenceObject->metaObject()->property(referencePropertyIndex).name(),
qPrintable(qmlBinding->expressionIdentifier()),
metaObject->property(pd->coreIndex()).name(),
- qPrintable(stackFrame->source()), stackFrame->line);
+ qPrintable(stackFrame->source()), stackFrame->lineNumber());
}
}
QQmlPropertyPrivate::removeBinding(referenceObject, QQmlPropertyIndex(referencePropertyIndex, pd->coreIndex()));
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 96c898e6d4..dcbe2b2a5b 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1342,7 +1342,7 @@ void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction
QQmlSourceLocation QQmlBindingFunction::currentLocation() const
{
QV4::CppStackFrame *frame = engine()->currentStackFrame;
- return QQmlSourceLocation(frame->source(), frame->line, 0);
+ return QQmlSourceLocation(frame->source(), frame->lineNumber(), 0);
}
DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
@@ -1552,7 +1552,7 @@ static ReturnedValue writeToConsole(const BuiltinFunction *b, CallData *callData
QV4::CppStackFrame *frame = v4->currentStackFrame;
const QByteArray baSource = frame->source().toUtf8();
const QByteArray baFunction = frame->function().toUtf8();
- QMessageLogger logger(baSource.constData(), frame->line, baFunction.constData(), loggingCategory->categoryName());
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData(), loggingCategory->categoryName());
switch (logType) {
case Log:
@@ -1606,7 +1606,7 @@ ReturnedValue ConsoleObject::method_profile(const BuiltinFunction *b, CallData *
QV4::CppStackFrame *frame = v4->currentStackFrame;
const QByteArray baSource = frame->source().toUtf8();
const QByteArray baFunction = frame->function().toUtf8();
- QMessageLogger logger(baSource.constData(), frame->line, baFunction.constData());
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData());
QQmlProfilerService *service = QQmlDebugConnector::service<QQmlProfilerService>();
if (!service) {
logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX.");
@@ -1626,7 +1626,7 @@ ReturnedValue ConsoleObject::method_profileEnd(const BuiltinFunction *b, CallDat
QV4::CppStackFrame *frame = v4->currentStackFrame;
const QByteArray baSource = frame->source().toUtf8();
const QByteArray baFunction = frame->function().toUtf8();
- QMessageLogger logger(baSource.constData(), frame->line, baFunction.constData());
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData());
QQmlProfilerService *service = QQmlDebugConnector::service<QQmlProfilerService>();
if (!service) {
@@ -1684,10 +1684,10 @@ ReturnedValue ConsoleObject::method_count(const BuiltinFunction *b, CallData *ca
QString scriptName = frame->source();
- int value = v8engine->consoleCountHelper(scriptName, frame->line, frame->column);
+ int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), -1);
QString message = name + QLatin1String(": ") + QString::number(value);
- QMessageLogger(qPrintable(scriptName), frame->line,
+ QMessageLogger(qPrintable(scriptName), frame->lineNumber(),
qPrintable(frame->function()))
.debug("%s", qPrintable(message));
@@ -1705,7 +1705,7 @@ ReturnedValue ConsoleObject::method_trace(const BuiltinFunction *b, CallData *ca
QString stack = jsStack(v4);
QV4::CppStackFrame *frame = v4->currentStackFrame;
- QMessageLogger(frame->source().toUtf8().constData(), frame->line,
+ QMessageLogger(frame->source().toUtf8().constData(), frame->lineNumber(),
frame->function().toUtf8().constData())
.debug("%s", qPrintable(stack));
@@ -1737,7 +1737,7 @@ ReturnedValue ConsoleObject::method_assert(const BuiltinFunction *b, CallData *c
QString stack = jsStack(v4);
QV4::CppStackFrame *frame = v4->currentStackFrame;
- QMessageLogger(frame->source().toUtf8().constData(), frame->line,
+ QMessageLogger(frame->source().toUtf8().constData(), frame->lineNumber(),
frame->function().toUtf8().constData())
.critical("%s\n%s",qPrintable(message), qPrintable(stack));