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>
This commit is contained in:
Lars Knoll 2017-08-21 10:59:53 +02:00 committed by Erik Verbruggen
parent 3c201dd0d9
commit 4e0174a88e
19 changed files with 128 additions and 71 deletions

View File

@ -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);
}

View File

@ -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());

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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) {

View File

@ -133,6 +133,7 @@ struct Context {
ControlFlow *controlFlow = 0;
QByteArray code;
QVector<int> lineNumberMapping;
int maxNumberOfArguments = 0;
bool hasDirectEval = false;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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();\

View File

@ -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()));
}
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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)

View File

@ -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()));

View File

@ -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));