diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-12-04 15:47:06 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-12-05 10:02:11 +0100 |
commit | cc66dd33cc44b5131c27d85daecf1b920f900f49 (patch) | |
tree | 4185a9060abc9ce04a5798dd93873ff7bb1e991c /src | |
parent | e2af7c3b37095e601a84cc52de69a99af8e5d3a2 (diff) |
Compiler: Support >32k stack slots
Previously, the code generator would truncate the stack slots when
writing the compiled function, as that one only had a 16bit field for
them.
Also, add a debug-mode check for stack overflows to the interpreter.
Unfortunately, as it triggers a stack overflow, the test will not
reliably fail without this change.
Fixes: QTBUG-80511
Change-Id: I3019bb2de657ae4c3e1040db798a83533f854bff
Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 35 |
2 files changed, 29 insertions, 16 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index c3ddce5884..1f5ad9bd86 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE // 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 +#define QV4_DATA_STRUCTURE_VERSION 0x25 // Extend size of "register" count (nRegisters) class QIODevice; class QQmlTypeNameCache; @@ -303,13 +303,15 @@ struct Function 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 + + quint32_le nRegisters; + Location location; + quint32_le nLabelInfos; + 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 diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index ad5a6ebc8c..e143523165 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -341,7 +341,17 @@ static struct InstrCount { } #endif -#define STACK_VALUE(temp) stack[temp] +static inline QV4::Value &stackValue(QV4::Value *stack, size_t slot, const CppStackFrame *frame) +{ + Q_ASSERT(slot < CallData::HeaderSize() / sizeof(QV4::StaticValue) + + frame->jsFrame->argc() + + frame->v4Function->compiledFunction->nRegisters); + Q_UNUSED(frame); + + return stack[slot]; +} + +#define STACK_VALUE(temp) stackValue(stack, temp, frame) // qv4scopedvalue_p.h also defines a CHECK_EXCEPTION macro #ifdef CHECK_EXCEPTION @@ -521,14 +531,14 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_END_INSTR(LoadImport) MOTH_BEGIN_INSTR(LoadLocal) - auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m()); + auto cc = static_cast<Heap::CallContext *>(STACK_VALUE(CallData::Context).m()); Q_ASSERT(cc->type != QV4::Heap::CallContext::Type_GlobalContext); acc = cc->locals[index].asReturnedValue(); MOTH_END_INSTR(LoadLocal) MOTH_BEGIN_INSTR(StoreLocal) CHECK_EXCEPTION; - auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m()); + auto cc = static_cast<Heap::CallContext *>(STACK_VALUE(CallData::Context).m()); Q_ASSERT(cc->type != QV4::Heap::CallContext::Type_GlobalContext); QV4::WriteBarrier::write(engine, cc, cc->locals.values[index].data_ptr(), acc); MOTH_END_INSTR(StoreLocal) @@ -714,7 +724,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_BEGIN_INSTR(CallProperty) STORE_IP(); - acc = Runtime::CallProperty::call(engine, stack[base], name, stack + argv, argc); + acc = Runtime::CallProperty::call(engine, STACK_VALUE(base), name, stack + argv, argc); CHECK_EXCEPTION; MOTH_END_INSTR(CallProperty) @@ -722,21 +732,21 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, STORE_IP(); Lookup *l = function->executableCompilationUnit()->runtimeLookups + lookupIndex; - if (stack[base].isNullOrUndefined()) { + if (STACK_VALUE(base).isNullOrUndefined()) { QString message = QStringLiteral("Cannot call method '%1' of %2") .arg(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]->toQString()) - .arg(stack[base].toQStringNoThrow()); + .arg(STACK_VALUE(base).toQStringNoThrow()); acc = engine->throwTypeError(message); goto handleUnwind; } // ok to have the value on the stack here - Value f = Value::fromReturnedValue(l->getter(l, engine, stack[base])); + Value f = Value::fromReturnedValue(l->getter(l, engine, STACK_VALUE(base))); if (Q_UNLIKELY(!f.isFunctionObject())) { QString message = QStringLiteral("Property '%1' of object %2 is not a function") .arg(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]->toQString()) - .arg(stack[base].toQStringNoThrow()); + .arg(STACK_VALUE(base).toQStringNoThrow()); acc = engine->throwTypeError(message); goto handleUnwind; } @@ -747,7 +757,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_BEGIN_INSTR(CallElement) STORE_IP(); - acc = Runtime::CallElement::call(engine, stack[base], STACK_VALUE(index), stack + argv, argc); + acc = Runtime::CallElement::call(engine, STACK_VALUE(base), STACK_VALUE(index), stack + argv, argc); CHECK_EXCEPTION; MOTH_END_INSTR(CallElement) @@ -864,7 +874,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_BEGIN_INSTR(PushWithContext) STORE_IP(); STORE_ACC(); - acc = Runtime::PushWithContext::call(engine, stack[CallData::Accumulator]); + acc = Runtime::PushWithContext::call(engine, STACK_VALUE(CallData::Accumulator)); CHECK_EXCEPTION; MOTH_END_INSTR(PushWithContext) @@ -971,12 +981,13 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, MOTH_BEGIN_INSTR(ConvertThisToObject) STORE_ACC(); - stack[CallData::This] = Runtime::ConvertThisToObject::call(engine, stack[CallData::This]); + stack[CallData::This] = Runtime::ConvertThisToObject::call( + engine, STACK_VALUE(CallData::This)); CHECK_EXCEPTION; MOTH_END_INSTR(ConvertThisToObject) MOTH_BEGIN_INSTR(LoadSuperConstructor) - acc = Runtime::LoadSuperConstructor::call(engine, stack[CallData::Function]); + acc = Runtime::LoadSuperConstructor::call(engine, STACK_VALUE(CallData::Function)); CHECK_EXCEPTION; MOTH_END_INSTR(LoadSuperConstructor) |