Protect CallContext member usage against word size differences

Ensure the offsets we're taking from ExecutionContext members in the JIT
code generator can be translated from host architecture sizes to target
architecture, using assertions and a memory layout that we already have
in the dev branch with commit 4de7e48ab1.

Change-Id: I1b26ef265234b05a6e5c8688a8aad2f33cd28783
Task-number: QTBUG-58666
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Simon Hausmann 2017-03-15 08:25:56 +01:00
parent cb4f4028ac
commit 7a125135e1
3 changed files with 21 additions and 5 deletions

View File

@ -95,7 +95,7 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType
QV4::ScopedContext it(scope, sctxt);
for (; it; it = it->d()->outer)
types.append(it->d()->type);
types.append(QV4::Heap::ExecutionContext::ContextType(it->d()->type));
return types;
}

View File

@ -290,7 +290,8 @@ typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>:
} break;
case IR::ArgLocal::Local:
case IR::ArgLocal::ScopedLocal: {
loadPtr(Address(baseReg, qOffsetOf(CallContext::Data, locals)), baseReg);
const qint32 localsOffset = targetStructureOffset(Heap::CallContext::baseOffset + offsetof(Heap::CallContextData, locals));
loadPtr(Address(baseReg, localsOffset), baseReg);
offset = al->index * sizeof(Value);
} break;
default:

View File

@ -150,12 +150,28 @@ struct ExecutionContext : Base, public ExecutionContextData {
lineNumber = -1;
}
ContextType type : 8;
quint8 type;
bool strictMode : 8;
#if QT_POINTER_SIZE == 8
quint8 padding_[6];
#else
quint8 padding_[2];
#endif
};
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE);
struct CallContext : ExecutionContext {
struct CallContextData {
Value *locals;
};
Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
Q_STATIC_ASSERT(offsetof(CallContextData, locals) == 0);
struct CallContextSizeStruct : public ExecutionContext, public CallContextData {};
struct CallContext : ExecutionContext, public CallContextData {
static Q_CONSTEXPR size_t baseOffset = sizeof(CallContextSizeStruct) - sizeof(CallContextData);
static CallContext *createSimpleContext(ExecutionEngine *v4);
void freeSimpleCallContext();
@ -168,7 +184,6 @@ struct CallContext : ExecutionContext {
Pointer<FunctionObject> function;
QV4::Function *v4Function;
Value *locals;
Pointer<Object> activation;
};
V4_ASSERT_IS_TRIVIAL(CallContext)