Fix endianness in constant handling
When running on a big-endian system, we need to convert the constant values into big-endian once and then it's possible to access them directly. Change-Id: I655bad7b7734e3b95e79e5f688f0b4041d0c41c4 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This commit is contained in:
parent
5b620ed689
commit
c25c95ba22
|
@ -161,6 +161,16 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
|
|||
}
|
||||
}
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
Value *bigEndianConstants = new Value[data->constantTableSize];
|
||||
const LEUInt64 *littleEndianConstants = data->constants();
|
||||
for (uint i = 0; i < data->constantTableSize; ++i)
|
||||
bigEndianConstants[i] = Value::fromReturnedValue(littleEndianConstants[i]);
|
||||
constants = bigEndianConstants;
|
||||
#else
|
||||
constants = reinterpret_cast<const Value*>(data->constants());
|
||||
#endif
|
||||
|
||||
linkBackendToEngine(engine);
|
||||
|
||||
if (data->indexOfRootFunction != -1)
|
||||
|
@ -203,6 +213,9 @@ void CompilationUnit::unlink()
|
|||
runtimeClasses = 0;
|
||||
qDeleteAll(runtimeFunctions);
|
||||
runtimeFunctions.clear();
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
delete [] constants;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
|
||||
|
|
|
@ -691,8 +691,8 @@ struct Unit
|
|||
const RegExp *regexpAt(int index) const {
|
||||
return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp));
|
||||
}
|
||||
const QV4::Value *constants() const {
|
||||
return reinterpret_cast<const QV4::Value*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
|
||||
const LEUInt64 *constants() const {
|
||||
return reinterpret_cast<const LEUInt64*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
|
||||
}
|
||||
|
||||
const JSClassMember *jsClassAt(int idx, int *nMembers) const {
|
||||
|
@ -853,6 +853,9 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
|
|||
QHash<int, IdentifierHash<int>> namedObjectsPerComponentCache;
|
||||
IdentifierHash<int> namedObjectsPerComponent(int componentObjectIndex);
|
||||
|
||||
// pointers either to data->constants() or little-endian memory copy.
|
||||
const Value* constants;
|
||||
|
||||
void finalize(QQmlEnginePrivate *engine);
|
||||
|
||||
int totalBindingsCount; // Number of bindings used in this type
|
||||
|
|
|
@ -248,8 +248,14 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
|
|||
CompiledData::RegExp *regexpTable = reinterpret_cast<CompiledData::RegExp *>(dataPtr + unit->offsetToRegexpTable);
|
||||
memcpy(regexpTable, regexps.constData(), regexps.size() * sizeof(*regexpTable));
|
||||
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
ReturnedValue *constantTable = reinterpret_cast<ReturnedValue *>(dataPtr + unit->offsetToConstantTable);
|
||||
memcpy(constantTable, constants.constData(), constants.size() * sizeof(ReturnedValue));
|
||||
#else
|
||||
CompiledData::LEUInt64 *constantTable = reinterpret_cast<CompiledData::LEUInt64 *>(dataPtr + unit->offsetToConstantTable);
|
||||
for (int i = 0; i < constants.count(); ++i)
|
||||
constantTable[i] = constants.at(i);
|
||||
#endif
|
||||
|
||||
{
|
||||
memcpy(dataPtr + jsClassDataOffset, jsClassData.constData(), jsClassData.size());
|
||||
|
|
|
@ -73,7 +73,7 @@ Heap::CallContext *ExecutionContext::newCallContext(const FunctionObject *functi
|
|||
|
||||
c->compilationUnit = function->function()->compilationUnit;
|
||||
c->lookups = c->compilationUnit->runtimeLookups;
|
||||
c->constantTable = c->compilationUnit->data->constants();
|
||||
c->constantTable = c->compilationUnit->constants;
|
||||
c->locals = (Value *)((quintptr(c + 1) + 7) & ~7);
|
||||
|
||||
const CompiledData::Function *compiledFunction = function->function()->compiledFunction;
|
||||
|
|
|
@ -535,7 +535,7 @@ void SimpleScriptFunction::construct(const Managed *that, Scope &scope, CallData
|
|||
ctx.function = f->d();
|
||||
ctx.compilationUnit = f->function()->compilationUnit;
|
||||
ctx.lookups = ctx.compilationUnit->runtimeLookups;
|
||||
ctx.constantTable = ctx.compilationUnit->data->constants();
|
||||
ctx.constantTable = ctx.compilationUnit->constants;
|
||||
ctx.outer = f->scope();
|
||||
ctx.locals = scope.alloc(f->varCount());
|
||||
for (int i = callData->argc; i < (int)f->formalParameterCount(); ++i)
|
||||
|
@ -573,7 +573,7 @@ void SimpleScriptFunction::call(const Managed *that, Scope &scope, CallData *cal
|
|||
ctx.function = f->d();
|
||||
ctx.compilationUnit = f->function()->compilationUnit;
|
||||
ctx.lookups = ctx.compilationUnit->runtimeLookups;
|
||||
ctx.constantTable = ctx.compilationUnit->data->constants();
|
||||
ctx.constantTable = ctx.compilationUnit->constants;
|
||||
ctx.outer = f->scope();
|
||||
ctx.locals = scope.alloc(f->varCount());
|
||||
for (int i = callData->argc; i < (int)f->formalParameterCount(); ++i)
|
||||
|
|
|
@ -222,7 +222,7 @@ ReturnedValue Script::run()
|
|||
ContextStateSaver stateSaver(valueScope, scope);
|
||||
scope->d()->strictMode = vmFunction->isStrict();
|
||||
scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups;
|
||||
scope->d()->constantTable = vmFunction->compilationUnit->data->constants();
|
||||
scope->d()->constantTable = vmFunction->compilationUnit->constants;
|
||||
scope->d()->compilationUnit = vmFunction->compilationUnit;
|
||||
|
||||
return Q_V4_PROFILE(engine, vmFunction);
|
||||
|
|
|
@ -402,7 +402,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
|
||||
QV4::Value **scopes = static_cast<QV4::Value **>(alloca(sizeof(QV4::Value *)*(2 + 2*scopeDepth)));
|
||||
{
|
||||
scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->data->constants());
|
||||
scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->constants);
|
||||
// stack gets setup in push instruction
|
||||
scopes[1] = 0;
|
||||
QV4::Heap::ExecutionContext *scope = context->d();
|
||||
|
|
Loading…
Reference in New Issue