QML: Introduce destroy() on Base subclasses

This removes the destructors of subclasses of Base, making them nearly
trivial.

Change-Id: Ia6f7d467e87899b5ad37b8709a8f633a51689d59
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Erik Verbruggen 2016-09-09 10:06:31 +02:00 committed by Erik Verbruggen
parent a166367bd8
commit 64afa01c32
34 changed files with 244 additions and 197 deletions

View File

@ -113,17 +113,26 @@ namespace Heap {
QQmlSqlDatabaseWrapper()
{
type = Database;
database = new QSqlDatabase;
version = new QString;
sqlQuery = new QSqlQuery;
}
void destroy() {
delete database;
delete version;
delete sqlQuery;
}
Type type;
QSqlDatabase database;
QSqlDatabase *database;
QString version; // type == Database
QString *version; // type == Database
bool inTransaction; // type == Query
bool readonly; // type == Query
QSqlQuery sqlQuery; // type == Rows
QSqlQuery *sqlQuery; // type == Rows
bool forwardOnly; // type == Rows
};
}
@ -160,7 +169,7 @@ static ReturnedValue qmlsqldatabase_version(CallContext *ctx)
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
return Encode(scope.engine->newString(r->d()->version));
return Encode(scope.engine->newString(*r->d()->version));
}
static ReturnedValue qmlsqldatabase_rows_length(CallContext *ctx)
@ -170,11 +179,11 @@ static ReturnedValue qmlsqldatabase_rows_length(CallContext *ctx)
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
int s = r->d()->sqlQuery.size();
int s = r->d()->sqlQuery->size();
if (s < 0) {
// Inefficient
if (r->d()->sqlQuery.last()) {
s = r->d()->sqlQuery.at() + 1;
if (r->d()->sqlQuery->last()) {
s = r->d()->sqlQuery->at() + 1;
} else {
s = 0;
}
@ -188,7 +197,7 @@ static ReturnedValue qmlsqldatabase_rows_forwardOnly(CallContext *ctx)
QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, ctx->thisObject().as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
return Encode(r->d()->sqlQuery.isForwardOnly());
return Encode(r->d()->sqlQuery->isForwardOnly());
}
static ReturnedValue qmlsqldatabase_rows_setForwardOnly(CallContext *ctx)
@ -200,7 +209,7 @@ static ReturnedValue qmlsqldatabase_rows_setForwardOnly(CallContext *ctx)
if (ctx->argc() < 1)
return ctx->engine()->throwTypeError();
r->d()->sqlQuery.setForwardOnly(ctx->args()[0].toBoolean());
r->d()->sqlQuery->setForwardOnly(ctx->args()[0].toBoolean());
return Encode::undefined();
}
@ -230,8 +239,8 @@ static ReturnedValue qmlsqldatabase_rows_index(const QQmlSqlDatabaseWrapper *r,
{
Scope scope(v4);
if (r->d()->sqlQuery.at() == (int)index || r->d()->sqlQuery.seek(index)) {
QSqlRecord record = r->d()->sqlQuery.record();
if (r->d()->sqlQuery->at() == (int)index || r->d()->sqlQuery->seek(index)) {
QSqlRecord record = r->d()->sqlQuery->record();
// XXX optimize
ScopedObject row(scope, v4->newObject());
for (int ii = 0; ii < record.count(); ++ii) {
@ -289,7 +298,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
if (!r->d()->inTransaction)
V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,QQmlEngine::tr("executeSql called outside transaction()"));
QSqlDatabase db = r->d()->database;
QSqlDatabase db = *r->d()->database;
QString sql = ctx->argc() ? ctx->args()[0].toQString() : QString();
@ -338,8 +347,8 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
QV4::ScopedObject p(scope, databaseData(scope.engine)->rowsProto.value());
rows->setPrototype(p.getPointer());
rows->d()->type = Heap::QQmlSqlDatabaseWrapper::Rows;
rows->d()->database = db;
rows->d()->sqlQuery = query;
*rows->d()->database = db;
*rows->d()->sqlQuery = query;
ScopedObject resultObject(scope, scope.engine->newObject());
result = resultObject.asReturnedValue();
@ -401,20 +410,20 @@ static ReturnedValue qmlsqldatabase_changeVersion(CallContext *ctx)
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
QSqlDatabase db = r->d()->database;
QSqlDatabase db = *r->d()->database;
QString from_version = ctx->args()[0].toQString();
QString to_version = ctx->args()[1].toQString();
ScopedFunctionObject callback(scope, ctx->argument(2));
if (from_version != r->d()->version)
V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(r->d()->version));
if (from_version != *r->d()->version)
V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(*r->d()->version));
Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
w->setPrototype(p.getPointer());
w->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
w->d()->database = db;
w->d()->version = r->d()->version;
*w->d()->database = db;
*w->d()->version = *r->d()->version;
bool ok = true;
if (!!callback) {
@ -437,7 +446,7 @@ static ReturnedValue qmlsqldatabase_changeVersion(CallContext *ctx)
}
if (ok) {
w->d()->version = to_version;
*w->d()->version = to_version;
#ifndef QT_NO_SETTINGS
QSettings ini(qmlsqldatabase_databaseFile(db.connectionName(), scope.engine) + QLatin1String(".ini"), QSettings::IniFormat);
ini.setValue(QLatin1String("Version"), to_version);
@ -458,14 +467,14 @@ static ReturnedValue qmlsqldatabase_transaction_shared(CallContext *ctx, bool re
if (!callback)
V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR, QQmlEngine::tr("transaction: missing callback"));
QSqlDatabase db = r->d()->database;
QSqlDatabase db = *r->d()->database;
Scoped<QQmlSqlDatabaseWrapper> w(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
QV4::ScopedObject p(scope, databaseData(scope.engine)->queryProto.value());
w->setPrototype(p.getPointer());
w->d()->type = Heap::QQmlSqlDatabaseWrapper::Query;
w->d()->database = db;
w->d()->version = r->d()->version;
*w->d()->database = db;
*w->d()->version = *r->d()->version;
w->d()->readonly = readOnly;
db.transaction();
@ -748,8 +757,8 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
QV4::Scoped<QQmlSqlDatabaseWrapper> db(scope, QQmlSqlDatabaseWrapper::create(scope.engine));
QV4::ScopedObject p(scope, databaseData(scope.engine)->databaseProto.value());
db->setPrototype(p.getPointer());
db->d()->database = database;
db->d()->version = version;
*db->d()->database = database;
*db->d()->version = version;
if (created && dbcreationCallback) {
ScopedCallData callData(scope, 1);

View File

@ -112,7 +112,7 @@ Heap::ArrayBuffer::ArrayBuffer(const QByteArray& array)
data->ref.ref();
}
Heap::ArrayBuffer::~ArrayBuffer()
void Heap::ArrayBuffer::destroy()
{
if (!data->ref.deref())
QTypedArrayData<char>::deallocate(data);

View File

@ -66,7 +66,7 @@ struct ArrayBufferCtor : FunctionObject {
struct Q_QML_PRIVATE_EXPORT ArrayBuffer : Object {
ArrayBuffer(size_t length);
ArrayBuffer(const QByteArray& array);
~ArrayBuffer();
void destroy();
QTypedArrayData<char> *data;
uint byteLength() const { return data->size; }

View File

@ -156,7 +156,7 @@ struct SimpleArrayData : public ArrayData {
Q_STATIC_ASSERT(std::is_trivial<SimpleArrayData>::value);
struct SparseArrayData : public ArrayData {
inline ~SparseArrayData();
void destroy() { delete sparse; }
uint mappedIndex(uint index) const {
SparseArrayNode *n = sparse->findNode(index);
@ -287,11 +287,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
namespace Heap {
inline SparseArrayData::~SparseArrayData()
{
delete sparse;
}
void ArrayData::getProperty(uint index, Property *p, PropertyAttributes *attrs)
{
Property *pd = getProperty(index);

View File

@ -69,7 +69,7 @@ QObject *QmlContext::qmlScope() const
QQmlContextData *QmlContext::qmlContext() const
{
return d()->qml->context;
return *d()->qml->context;
}
void QmlContext::takeContextOwnership() {

View File

@ -744,7 +744,7 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const
if (!ctx)
return 0;
return ctx->qml->context.contextData();
return ctx->qml->context->contextData();
}
QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
@ -920,7 +920,7 @@ ReturnedValue ExecutionEngine::throwError(const Value &value)
QV4::Scope scope(this);
QV4::Scoped<ErrorObject> error(scope, value);
if (!!error)
exceptionStackTrace = error->d()->stackTrace;
exceptionStackTrace = *error->d()->stackTrace;
else
exceptionStackTrace = stackTrace();
@ -1153,7 +1153,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return str;
}
if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>())
return ld->d()->locale;
return *ld->d()->locale;
if (const QV4::DateObject *d = value.as<DateObject>())
return d->toQDateTime();
if (const ArrayBuffer *d = value.as<ArrayBuffer>())

View File

@ -69,6 +69,8 @@ using namespace QV4;
Heap::ErrorObject::ErrorObject()
{
stackTrace = nullptr;
Scope scope(internalClass->engine);
Scoped<QV4::ErrorObject> e(scope, this);
@ -91,10 +93,10 @@ Heap::ErrorObject::ErrorObject(const Value &message, ErrorType t)
*propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction();
*propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined();
e->d()->stackTrace = scope.engine->stackTrace();
if (!e->d()->stackTrace.isEmpty()) {
*propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace.at(0).source);
*propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace.at(0).line);
e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
if (!e->d()->stackTrace->isEmpty()) {
*propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source);
*propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line);
}
if (!message.isUndefined())
@ -111,16 +113,16 @@ Heap::ErrorObject::ErrorObject(const Value &message, const QString &fileName, in
*propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction();
*propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined();
e->d()->stackTrace = scope.engine->stackTrace();
e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
StackFrame frame;
frame.source = fileName;
frame.line = line;
frame.column = column;
e->d()->stackTrace.prepend(frame);
e->d()->stackTrace->prepend(frame);
if (!e->d()->stackTrace.isEmpty()) {
*propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace.at(0).source);
*propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace.at(0).line);
if (!e->d()->stackTrace->isEmpty()) {
*propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source);
*propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line);
}
if (!message.isUndefined())
@ -156,10 +158,10 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
return ctx->engine()->throwTypeError();
if (!This->d()->stack) {
QString trace;
for (int i = 0; i < This->d()->stackTrace.count(); ++i) {
for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
if (i > 0)
trace += QLatin1Char('\n');
const StackFrame &frame = This->d()->stackTrace[i];
const StackFrame &frame = This->d()->stackTrace->at(i);
trace += frame.function + QLatin1Char('@') + frame.source;
if (frame.line >= 0)
trace += QLatin1Char(':') + QString::number(frame.line);

View File

@ -76,9 +76,10 @@ struct ErrorObject : Object {
ErrorObject();
ErrorObject(const Value &message, ErrorType t = Error);
ErrorObject(const Value &message, const QString &fileName, int line, int column, ErrorType t = Error);
void destroy() { delete stackTrace; }
ErrorType errorType;
StackTrace stackTrace;
StackTrace *stackTrace;
Pointer<String> stack;
};

View File

@ -136,7 +136,7 @@ Heap::FunctionObject::FunctionObject()
}
Heap::FunctionObject::~FunctionObject()
void Heap::FunctionObject::destroy()
{
if (function)
function->compilationUnit->release();

View File

@ -76,7 +76,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name);
FunctionObject(ExecutionContext *scope, const ReturnedValue name);
FunctionObject();
~FunctionObject();
void destroy();
unsigned int formalParameterCount() { return function ? function->nFormals : 0; }
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }

View File

@ -74,7 +74,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
#define V4_MANAGED_SIZE_TEST
#endif
#define V4_NEEDS_DESTROY static void destroy(QV4::Heap::Base *b) { static_cast<Data *>(b)->~Data(); }
#define V4_NEEDS_DESTROY static void destroy(QV4::Heap::Base *b) { static_cast<Data *>(b)->destroy(); }
#define V4_MANAGED_ITSELF(DataClass, superClass) \

View File

@ -1847,7 +1847,7 @@ Heap::QMetaObjectWrapper::QMetaObjectWrapper(const QMetaObject *metaObject)
, constructorCount(0)
{}
Heap::QMetaObjectWrapper::~QMetaObjectWrapper()
void Heap::QMetaObjectWrapper::destroy()
{
delete[] constructors;
}

View File

@ -79,7 +79,7 @@ struct QQmlValueTypeWrapper;
struct QObjectWrapper : Object {
QObjectWrapper(QObject *object);
~QObjectWrapper() { qObj.destroy(); }
void destroy() { qObj.destroy(); }
QObject *object() const { return qObj.data(); }
@ -89,7 +89,13 @@ private:
struct QObjectMethod : FunctionObject {
QObjectMethod(QV4::ExecutionContext *scope);
~QObjectMethod() { qObj.destroy(); }
void destroy()
{
propertyCache = nullptr;
qObj.destroy();
FunctionObject::destroy();
}
QQmlRefPointer<QQmlPropertyCache> propertyCache;
int index;
@ -109,13 +115,13 @@ struct QMetaObjectWrapper : FunctionObject {
int constructorCount;
QMetaObjectWrapper(const QMetaObject* metaObject);
~QMetaObjectWrapper();
void destroy();
void ensureConstructorsCache();
};
struct QmlSignalHandler : Object {
QmlSignalHandler(QObject *object, int signalIndex);
~QmlSignalHandler() { qObj.destroy(); }
void destroy() { qObj.destroy(); }
int signalIndex;
QObject *object() const { return qObj.data(); }
@ -130,6 +136,7 @@ private:
struct Q_QML_EXPORT QObjectWrapper : public Object
{
V4_OBJECT2(QObjectWrapper, Object)
V4_NEEDS_DESTROY
enum RevisionMode { IgnoreRevision, CheckRevision };

View File

@ -62,8 +62,8 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
WTF::String s(string);
#if ENABLE(YARR_JIT)
if (!jitCode().isFallBack() && jitCode().has16BitCode())
return uint(jitCode().execute(s.characters16(), start, s.length(), (int*)matchOffsets).start);
if (!jitCode()->isFallBack() && jitCode()->has16BitCode())
return uint(jitCode()->execute(s.characters16(), start, s.length(), (int*)matchOffsets).start);
#endif
return JSC::Yarr::interpret(byteCode().get(), s.characters16(), string.length(), start, matchOffsets);
@ -104,19 +104,23 @@ Heap::RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignor
subPatternCount = yarrPattern.m_numSubpatterns;
byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator);
#if ENABLE(YARR_JIT)
jitCode = new JSC::Yarr::YarrCodeBlock;
if (!yarrPattern.m_containsBackreferences && engine->iselFactory->jitCompileRegexps()) {
JSC::JSGlobalData dummy(engine->regExpAllocator);
JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, jitCode);
JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, *jitCode);
}
#endif
}
Heap::RegExp::~RegExp()
void Heap::RegExp::destroy()
{
if (cache) {
RegExpCacheKey key(this);
cache->remove(key);
}
#if ENABLE(YARR_JIT)
delete jitCode;
#endif
}
void RegExp::markObjects(Heap::Base *that, ExecutionEngine *e)

View File

@ -77,11 +77,12 @@ namespace Heap {
struct RegExp : Base {
RegExp(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline);
~RegExp();
void destroy();
QString pattern;
OwnPtr<JSC::Yarr::BytecodePattern> byteCode;
#if ENABLE(YARR_JIT)
JSC::Yarr::YarrCodeBlock jitCode;
JSC::Yarr::YarrCodeBlock *jitCode;
#endif
RegExpCache *cache;
int subPatternCount;
@ -102,7 +103,7 @@ struct RegExp : public Managed
QString pattern() const { return d()->pattern; }
OwnPtr<JSC::Yarr::BytecodePattern> &byteCode() { return d()->byteCode; }
#if ENABLE(YARR_JIT)
JSC::Yarr::YarrCodeBlock jitCode() const { return d()->jitCode; }
JSC::Yarr::YarrCodeBlock *jitCode() const { return d()->jitCode; }
#endif
RegExpCache *cache() const { return d()->cache; }
int subPatternCount() const { return d()->subPatternCount; }

View File

@ -1462,7 +1462,7 @@ ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine,
ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->context->contextObject, propertyIndex, captureRequired);
return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, captureRequired);
}
ReturnedValue Runtime::method_getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
@ -1480,7 +1480,7 @@ ReturnedValue Runtime::method_getQmlIdObject(ExecutionEngine *engine, const Valu
{
Scope scope(engine);
const QmlContext &qmlContext = static_cast<const QmlContext &>(c);
QQmlContextData *context = qmlContext.d()->qml->context;
QQmlContextData *context = *qmlContext.d()->qml->context;
if (!context || index >= (uint)context->idValueCount)
return Encode::undefined();
@ -1500,7 +1500,7 @@ void Runtime::method_setQmlScopeObjectProperty(ExecutionEngine *engine, const Va
void Runtime::method_setQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
return QV4::QObjectWrapper::setProperty(engine, c.d()->qml->context->contextObject, propertyIndex, value);
return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, value);
}
void Runtime::method_setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)

View File

@ -218,9 +218,12 @@ template <typename Container>
struct QQmlSequence : Object {
QQmlSequence(const Container &container);
QQmlSequence(QObject *object, int propertyIndex);
~QQmlSequence() { object.destroy(); }
void destroy() {
delete container;
object.destroy();
}
mutable Container container;
mutable Container *container;
QQmlQPointer<QObject> object;
int propertyIndex;
bool isReference;
@ -260,10 +263,10 @@ public:
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
if (signedIdx < d()->container.count()) {
if (signedIdx < d()->container->count()) {
if (hasProperty)
*hasProperty = true;
return convertElementToValue(engine(), d()->container.at(signedIdx));
return convertElementToValue(engine(), d()->container->at(signedIdx));
}
if (hasProperty)
*hasProperty = false;
@ -289,22 +292,22 @@ public:
qint32 signedIdx = static_cast<qint32>(index);
int count = d()->container.count();
int count = d()->container->count();
typename Container::value_type element = convertValueToElement<typename Container::value_type>(value);
if (signedIdx == count) {
d()->container.append(element);
d()->container->append(element);
} else if (signedIdx < count) {
d()->container[signedIdx] = element;
(*d()->container)[signedIdx] = element;
} else {
/* according to ECMA262r3 we need to insert */
/* the value at the given index, increasing length to index+1. */
d()->container.reserve(signedIdx + 1);
d()->container->reserve(signedIdx + 1);
while (signedIdx > count++) {
d()->container.append(typename Container::value_type());
d()->container->append(typename Container::value_type());
}
d()->container.append(element);
d()->container->append(element);
}
if (d()->isReference)
@ -324,7 +327,7 @@ public:
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
return (signedIdx < d()->container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
return (signedIdx < d()->container->count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
}
void containerAdvanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
@ -340,11 +343,11 @@ public:
loadReference();
}
if (it->arrayIndex < static_cast<uint>(d()->container.count())) {
if (it->arrayIndex < static_cast<uint>(d()->container->count())) {
*index = it->arrayIndex;
++it->arrayIndex;
*attrs = QV4::Attr_Data;
p->value = convertElementToValue(engine(), d()->container.at(*index));
p->value = convertElementToValue(engine(), d()->container->at(*index));
return;
}
QV4::Object::advanceIterator(this, it, name, index, p, attrs);
@ -362,12 +365,12 @@ public:
}
qint32 signedIdx = static_cast<qint32>(index);
if (signedIdx >= d()->container.count())
if (signedIdx >= d()->container->count())
return false;
/* according to ECMA262r3 it should be Undefined, */
/* but we cannot, so we insert a default-value instead. */
d()->container.replace(signedIdx, typename Container::value_type());
d()->container->replace(signedIdx, typename Container::value_type());
if (d()->isReference)
storeReference();
@ -432,10 +435,10 @@ public:
QV4::Scope scope(ctx);
if (ctx->argc() == 1 && ctx->args()[0].as<FunctionObject>()) {
CompareFunctor cf(ctx, ctx->args()[0]);
std::sort(d()->container.begin(), d()->container.end(), cf);
std::sort(d()->container->begin(), d()->container->end(), cf);
} else {
DefaultCompareFunctor cf;
std::sort(d()->container.begin(), d()->container.end(), cf);
std::sort(d()->container->begin(), d()->container->end(), cf);
}
if (d()->isReference)
@ -454,7 +457,7 @@ public:
return QV4::Encode(0);
This->loadReference();
}
return QV4::Encode(This->d()->container.count());
return QV4::Encode(This->d()->container->count());
}
static QV4::ReturnedValue method_set_length(QV4::CallContext* ctx)
@ -478,23 +481,23 @@ public:
}
/* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength);
qint32 count = This->d()->container.count();
qint32 count = This->d()->container->count();
if (newCount == count) {
return QV4::Encode::undefined();
} else if (newCount > count) {
/* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */
/* We cannot, so we insert default-values instead. */
This->d()->container.reserve(newCount);
This->d()->container->reserve(newCount);
while (newCount > count++) {
This->d()->container.append(typename Container::value_type());
This->d()->container->append(typename Container::value_type());
}
} else {
/* according to ECMA262r3 we need to remove */
/* elements until the sequence is the required length. */
while (newCount < count) {
count--;
This->d()->container.removeAt(count);
This->d()->container->removeAt(count);
}
}
/* write back if required. */
@ -506,7 +509,7 @@ public:
}
QVariant toVariant() const
{ return QVariant::fromValue<Container>(d()->container); }
{ return QVariant::fromValue<Container>(*d()->container); }
static QVariant toVariant(QV4::ArrayObject *array)
{
@ -523,7 +526,7 @@ public:
{
Q_ASSERT(d()->object);
Q_ASSERT(d()->isReference);
void *a[] = { &d()->container, 0 };
void *a[] = { d()->container, 0 };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->propertyIndex, a);
}
@ -533,7 +536,7 @@ public:
Q_ASSERT(d()->isReference);
int status = -1;
QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding;
void *a[] = { &d()->container, 0, &status, &flags };
void *a[] = { d()->container, 0, &status, &flags };
QMetaObject::metacall(d()->object, QMetaObject::WriteProperty, d()->propertyIndex, a);
}
@ -555,7 +558,7 @@ public:
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(const Container &container)
: container(container)
: container(new Container(container))
, propertyIndex(-1)
, isReference(false)
{
@ -569,7 +572,8 @@ Heap::QQmlSequence<Container>::QQmlSequence(const Container &container)
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(QObject *object, int propertyIndex)
: propertyIndex(propertyIndex)
: container(new Container)
, propertyIndex(propertyIndex)
, isReference(true)
{
this->object.init(object);

View File

@ -73,7 +73,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
#ifndef V4_BOOTSTRAP
String(MemoryManager *mm, const QString &text);
String(MemoryManager *mm, String *l, String *n, bool dummy);
~String() {
void destroy() {
if (!largestSubLength && !text->ref.deref())
QStringData::deallocate(text);
}

View File

@ -68,7 +68,7 @@ struct VariantObject : Object
{
VariantObject();
VariantObject(const QVariant &value);
~VariantObject() {
void destroy() {
Q_ASSERT(scarceData);
if (isScarce())
addVmePropertyReference();

View File

@ -256,24 +256,27 @@ public:
template <typename ManagedType>
typename ManagedType::Data *alloc()
{
Q_STATIC_ASSERT(std::is_trivial<typename ManagedType::Data>::value); // TODO: move down to allocManaged
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
(void)new (t->d()) typename ManagedType::Data();
t->d_unchecked()->init();
return t->d();
}
template <typename ManagedType, typename Arg1>
typename ManagedType::Data *alloc(Arg1 arg1)
{
Q_STATIC_ASSERT(std::is_trivial<typename ManagedType::Data>::value); // TODO: move down to allocManaged
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
(void)new (t->d()) typename ManagedType::Data(arg1);
t->d_unchecked()->init(arg1);
return t->d();
}
template <typename ManagedType, typename Arg1, typename Arg2>
typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2)
{
Q_STATIC_ASSERT(std::is_trivial<typename ManagedType::Data>::value); // TODO: move down to allocManaged
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
t->d_unchecked()->init(arg1, arg2);
@ -283,6 +286,7 @@ public:
template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3>
typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
{
Q_STATIC_ASSERT(std::is_trivial<typename ManagedType::Data>::value); // TODO: move down to allocManaged
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
t->d_unchecked()->init(arg1, arg2, arg3);
@ -301,9 +305,10 @@ public:
template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
{
Q_STATIC_ASSERT(std::is_trivial<typename ManagedType::Data>::value); // TODO: move down to allocManaged
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
(void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5);
t->d_unchecked()->init(arg1, arg2, arg3, arg4, arg5);
return t->d();
}

View File

@ -1059,8 +1059,8 @@ namespace Heap {
struct QmlIncubatorObject : Object {
QmlIncubatorObject(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous);
~QmlIncubatorObject() { parent.destroy(); }
QScopedPointer<QQmlComponentIncubator> incubator;
inline void destroy();
QQmlComponentIncubator *incubator;
QQmlQPointer<QObject> parent;
QV4::Value valuemap;
QV4::Value statusChanged;
@ -1389,7 +1389,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
r->d()->qmlContext = v4->qmlContext();
r->d()->parent = parent;
QQmlIncubator *incubator = r->d()->incubator.data();
QQmlIncubator *incubator = r->d()->incubator;
create(*incubator, creationContext());
if (incubator->status() == QQmlIncubator::Null) {
@ -1490,7 +1490,12 @@ QV4::Heap::QmlIncubatorObject::QmlIncubatorObject(QQmlIncubator::IncubationMode
{
parent.init();
qmlContext = nullptr;
incubator.reset(new QQmlComponentIncubator(this, m));
incubator = new QQmlComponentIncubator(this, m);
}
void QV4::Heap::QmlIncubatorObject::destroy() {
delete incubator;
parent.destroy();
}
void QV4::QmlIncubatorObject::setInitialState(QObject *o)

View File

@ -65,15 +65,16 @@ Heap::QmlContextWrapper::QmlContextWrapper(QQmlContextData *context, QObject *sc
: readOnly(true)
, ownsContext(ownsContext)
, isNullWrapper(false)
, context(context)
{
this->context = new QQmlGuardedContextData(context);
this->scopeObject.init(scopeObject);
}
Heap::QmlContextWrapper::~QmlContextWrapper()
void Heap::QmlContextWrapper::destroy()
{
if (context && ownsContext)
context->destroy();
if (*context && ownsContext)
(*context)->destroy();
delete context;
scopeObject.destroy();
}
@ -120,7 +121,7 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
if (resource->d()->isNullWrapper)
return Object::get(m, name, hasProperty);
if (v4->callingQmlContext() != resource->d()->context)
if (v4->callingQmlContext() != *resource->d()->context)
return Object::get(m, name, hasProperty);
result = Object::get(m, name, &hasProp);

View File

@ -65,12 +65,12 @@ namespace Heap {
struct QmlContextWrapper : Object {
QmlContextWrapper(QQmlContextData *context, QObject *scopeObject, bool ownsContext = false);
~QmlContextWrapper();
void destroy();
bool readOnly;
bool ownsContext;
bool isNullWrapper;
QQmlGuardedContextData context;
QQmlGuardedContextData *context;
QQmlQPointer<QObject> scopeObject;
};
@ -89,7 +89,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
}
inline QObject *getScopeObject() const { return d()->scopeObject; }
inline QQmlContextData *getContext() const { return d()->context; }
inline QQmlContextData *getContext() const { return *d()->context; }
void setReadOnly(bool b) { d()->readOnly = b; }

View File

@ -60,7 +60,7 @@ Heap::QmlListWrapper::QmlListWrapper()
o->setArrayType(Heap::ArrayData::Custom);
}
Heap::QmlListWrapper::~QmlListWrapper()
void Heap::QmlListWrapper::destroy()
{
object.destroy();
}

View File

@ -67,7 +67,7 @@ namespace Heap {
struct QmlListWrapper : Object {
QmlListWrapper();
~QmlListWrapper();
void destroy();
QQmlQPointer<QObject> object;
QQmlListProperty<QObject> property;
int propertyType;

View File

@ -109,16 +109,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ct
if (ctx->argc() == 2) {
if (ctx->args()[1].isString()) {
QString format = ctx->args()[1].stringValue()->toQString();
formattedDt = r->d()->locale.toString(dt, format);
formattedDt = r->d()->locale->toString(dt, format);
} else if (ctx->args()[1].isNumber()) {
quint32 intFormat = ctx->args()[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDt = r->d()->locale.toString(dt, format);
formattedDt = r->d()->locale->toString(dt, format);
} else {
V4THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
}
} else {
formattedDt = r->d()->locale.toString(dt, enumFormat);
formattedDt = r->d()->locale->toString(dt, enumFormat);
}
return ctx->d()->engine->newString(formattedDt)->asReturnedValue();
@ -154,16 +154,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext
if (ctx->argc() == 2) {
if (ctx->args()[1].isString()) {
QString format = ctx->args()[1].stringValue()->toQString();
formattedTime = r->d()->locale.toString(time, format);
formattedTime = r->d()->locale->toString(time, format);
} else if (ctx->args()[1].isNumber()) {
quint32 intFormat = ctx->args()[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedTime = r->d()->locale.toString(time, format);
formattedTime = r->d()->locale->toString(time, format);
} else {
V4THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
}
} else {
formattedTime = r->d()->locale.toString(time, enumFormat);
formattedTime = r->d()->locale->toString(time, enumFormat);
}
return ctx->d()->engine->newString(formattedTime)->asReturnedValue();
@ -199,16 +199,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext
if (ctx->argc() == 2) {
if (ctx->args()[1].isString()) {
QString format = ctx->args()[1].stringValue()->toQString();
formattedDate = r->d()->locale.toString(date, format);
formattedDate = r->d()->locale->toString(date, format);
} else if (ctx->args()[1].isNumber()) {
quint32 intFormat = ctx->args()[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDate = r->d()->locale.toString(date, format);
formattedDate = r->d()->locale->toString(date, format);
} else {
V4THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
}
} else {
formattedDate = r->d()->locale.toString(date, enumFormat);
formattedDate = r->d()->locale->toString(date, enumFormat);
}
return ctx->d()->engine->newString(formattedDate)->asReturnedValue();
@ -237,16 +237,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::CallContext *
if (ctx->argc() == 3) {
if (ctx->args()[2].isString()) {
QString format = ctx->args()[2].stringValue()->toQString();
dt = r->d()->locale.toDateTime(dateString, format);
dt = r->d()->locale->toDateTime(dateString, format);
} else if (ctx->args()[2].isNumber()) {
quint32 intFormat = ctx->args()[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale.toDateTime(dateString, format);
dt = r->d()->locale->toDateTime(dateString, format);
} else {
V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
}
} else {
dt = r->d()->locale.toDateTime(dateString, enumFormat);
dt = r->d()->locale->toDateTime(dateString, enumFormat);
}
return QV4::Encode(engine->newDateObject(dt));
@ -278,16 +278,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte
if (ctx->argc() == 3) {
if (ctx->args()[2].isString()) {
QString format = ctx->args()[2].stringValue()->toQString();
tm = r->d()->locale.toTime(dateString, format);
tm = r->d()->locale->toTime(dateString, format);
} else if (ctx->args()[2].isNumber()) {
quint32 intFormat = ctx->args()[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
tm = r->d()->locale.toTime(dateString, format);
tm = r->d()->locale->toTime(dateString, format);
} else {
V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
}
} else {
tm = r->d()->locale.toTime(dateString, enumFormat);
tm = r->d()->locale->toTime(dateString, enumFormat);
}
QDateTime dt;
@ -323,16 +323,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::CallConte
if (ctx->argc() == 3) {
if (ctx->args()[2].isString()) {
QString format = ctx->args()[2].stringValue()->toQString();
dt = r->d()->locale.toDate(dateString, format);
dt = r->d()->locale->toDate(dateString, format);
} else if (ctx->args()[2].isNumber()) {
quint32 intFormat = ctx->args()[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale.toDate(dateString, format);
dt = r->d()->locale->toDate(dateString, format);
} else {
V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
}
} else {
dt = r->d()->locale.toDate(dateString, enumFormat);
dt = r->d()->locale->toDate(dateString, enumFormat);
}
return QV4::Encode(engine->newDateObject(QDateTime(dt)));
@ -393,7 +393,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *
prec = ctx->args()[2].toInt32();
}
return ctx->d()->engine->newString(r->d()->locale.toString(number, (char)format, prec))->asReturnedValue();
return ctx->d()->engine->newString(r->d()->locale->toString(number, (char)format, prec))->asReturnedValue();
}
QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallContext *ctx)
@ -423,7 +423,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallC
symbol = ctx->args()[1].toQStringNoThrow();
}
return ctx->d()->engine->newString(r->d()->locale.toCurrencyString(number, symbol))->asReturnedValue();
return ctx->d()->engine->newString(r->d()->locale->toCurrencyString(number, symbol))->asReturnedValue();
}
QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext *ctx)
@ -441,7 +441,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext
V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
locale = r->d()->locale;
locale = *r->d()->locale;
numberIdx = 1;
}
@ -813,7 +813,7 @@ QV4::ReturnedValue QQmlLocale::wrap(ExecutionEngine *v4, const QLocale &locale)
QV4::Scope scope(v4);
QV4LocaleDataDeletable *d = localeV4Data(scope.engine);
QV4::Scoped<QQmlLocaleData> wrapper(scope, v4->memoryManager->allocObject<QQmlLocaleData>());
wrapper->d()->locale = locale;
*wrapper->d()->locale = locale;
QV4::ScopedObject p(scope, d->prototype.value());
wrapper->setPrototype(p);
return wrapper.asReturnedValue();

View File

@ -143,8 +143,9 @@ namespace QV4 {
namespace Heap {
struct QQmlLocaleData : Object {
inline QQmlLocaleData() {}
QLocale locale;
inline QQmlLocaleData() { locale = new QLocale; }
void destroy() { delete locale; }
QLocale *locale;
};
}
@ -161,7 +162,7 @@ struct QQmlLocaleData : public QV4::Object
ctx->engine()->throwTypeError();
return 0;
}
return &thisObject->d()->locale;
return thisObject->d()->locale;
}
static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx);

View File

@ -61,7 +61,7 @@ Heap::QmlTypeWrapper::QmlTypeWrapper()
object.init();
}
Heap::QmlTypeWrapper::~QmlTypeWrapper()
void Heap::QmlTypeWrapper::destroy()
{
if (typeNamespace)
typeNamespace->release();

View File

@ -72,7 +72,7 @@ struct QmlTypeWrapper : Object {
};
QmlTypeWrapper();
~QmlTypeWrapper();
void destroy();
TypeNameMode mode;
QQmlQPointer<QObject> object;

View File

@ -175,17 +175,24 @@ namespace Heap {
struct NamedNodeMap : Object {
NamedNodeMap(NodeImpl *data, const QList<NodeImpl *> &list);
~NamedNodeMap() {
void destroy() {
delete listPtr;
if (d)
d->release();
}
QList<NodeImpl *> list; // Only used in NamedNodeMap
QList<NodeImpl *> &list() {
if (listPtr == nullptr)
listPtr = new QList<NodeImpl *>;
return *listPtr;
}
QList<NodeImpl *> *listPtr; // Only used in NamedNodeMap
NodeImpl *d;
};
struct NodeList : Object {
NodeList(NodeImpl *data);
~NodeList() {
void destroy() {
if (d)
d->release();
}
@ -198,7 +205,7 @@ struct NodePrototype : Object {
struct Node : Object {
Node(NodeImpl *data);
~Node() {
void destroy() {
if (d)
d->release();
}
@ -222,9 +229,9 @@ public:
};
Heap::NamedNodeMap::NamedNodeMap(NodeImpl *data, const QList<NodeImpl *> &list)
: list(list)
, d(data)
: d(data)
{
this->list() = list;
if (d)
d->addref();
}
@ -877,10 +884,10 @@ ReturnedValue NamedNodeMap::getIndexed(const Managed *m, uint index, bool *hasPr
const NamedNodeMap *r = static_cast<const NamedNodeMap *>(m);
QV4::ExecutionEngine *v4 = r->engine();
if ((int)index < r->d()->list.count()) {
if ((int)index < r->d()->list().count()) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->list.at(index));
return Node::create(v4, r->d()->list().at(index));
}
if (hasProperty)
*hasProperty = false;
@ -895,14 +902,14 @@ ReturnedValue NamedNodeMap::get(const Managed *m, String *name, bool *hasPropert
name->makeIdentifier(v4);
if (name->equals(v4->id_length()))
return Primitive::fromInt32(r->d()->list.count()).asReturnedValue();
return Primitive::fromInt32(r->d()->list().count()).asReturnedValue();
QString str = name->toQString();
for (int ii = 0; ii < r->d()->list.count(); ++ii) {
if (r->d()->list.at(ii)->name == str) {
for (int ii = 0; ii < r->d()->list().count(); ++ii) {
if (r->d()->list().at(ii)->name == str) {
if (hasProperty)
*hasProperty = true;
return Node::create(v4, r->d()->list.at(ii));
return Node::create(v4, r->d()->list().at(ii));
}
}
@ -1588,7 +1595,7 @@ namespace Heap {
struct QQmlXMLHttpRequestWrapper : Object {
QQmlXMLHttpRequestWrapper(QQmlXMLHttpRequest *request);
~QQmlXMLHttpRequestWrapper() {
void destroy() {
delete request;
}
QQmlXMLHttpRequest *request;

View File

@ -76,7 +76,8 @@ struct QQmlDelegateModelGroupChange : Object {
struct QQmlDelegateModelGroupChangeArray : Object {
QQmlDelegateModelGroupChangeArray(const QVector<QQmlChangeSet::Change> &changes);
QVector<QQmlChangeSet::Change> changes;
void destroy() { delete changes; }
QVector<QQmlChangeSet::Change> *changes;
};
@ -1865,7 +1866,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisI
DEFINE_OBJECT_VTABLE(QQmlDelegateModelItemObject);
QV4::Heap::QQmlDelegateModelItemObject::~QQmlDelegateModelItemObject()
void QV4::Heap::QQmlDelegateModelItemObject::destroy()
{
item->Dispose();
}
@ -3256,8 +3257,8 @@ public:
return engine->memoryManager->allocObject<QQmlDelegateModelGroupChangeArray>(changes);
}
quint32 count() const { return d()->changes.count(); }
const QQmlChangeSet::Change &at(int index) const { return d()->changes.at(index); }
quint32 count() const { return d()->changes->count(); }
const QQmlChangeSet::Change &at(int index) const { return d()->changes->at(index); }
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
{
@ -3300,7 +3301,7 @@ public:
};
QV4::Heap::QQmlDelegateModelGroupChangeArray::QQmlDelegateModelGroupChangeArray(const QVector<QQmlChangeSet::Change> &changes)
: changes(changes)
: changes(new QVector<QQmlChangeSet::Change>(changes))
{
QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);

View File

@ -161,7 +161,7 @@ namespace QV4 {
namespace Heap {
struct QQmlDelegateModelItemObject : Object {
inline QQmlDelegateModelItemObject(QQmlDelegateModelItem *item);
~QQmlDelegateModelItemObject();
void destroy();
QQmlDelegateModelItem *item;
};

View File

@ -500,19 +500,22 @@ struct QQuickJSContext2DPrototype : Object {
struct QQuickContext2DStyle : Object {
QQuickContext2DStyle()
{
brush = new QBrush;
patternRepeatX = false;
patternRepeatY = false;
}
void destroy() { delete brush; }
QBrush brush;
QBrush *brush;
bool patternRepeatX:1;
bool patternRepeatY:1;
};
struct QQuickJSContext2DPixelData : Object {
QQuickJSContext2DPixelData();
void destroy() { delete image; }
QImage image;
QImage *image;
};
struct QQuickJSContext2DImageData : Object {
@ -899,6 +902,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
QV4::Heap::QQuickJSContext2DPixelData::QQuickJSContext2DPixelData()
{
image = new QImage;
QV4::Scope scope(internalClass->engine);
QV4::ScopedObject o(scope, this);
o->setArrayType(QV4::Heap::ArrayData::Custom);
@ -943,11 +947,11 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
pixelData->setPrototype(p);
if (image.isNull()) {
pixelData->d()->image = QImage(w, h, QImage::Format_ARGB32);
pixelData->d()->image.fill(0x00000000);
*pixelData->d()->image = QImage(w, h, QImage::Format_ARGB32);
pixelData->d()->image->fill(0x00000000);
} else {
Q_ASSERT(image.width() == qRound(w) && image.height() == qRound(h));
pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
*pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
}
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, scope.engine->memoryManager->allocObject<QQuickJSContext2DImageData>());
@ -1392,9 +1396,9 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
r->d()->context->m_fillStyle.set(scope.engine, value);
} else {
QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
if (style && style->d()->brush != r->d()->context->state.fillStyle) {
r->d()->context->state.fillStyle = style->d()->brush;
r->d()->context->buffer()->setFillStyle(style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
if (style && *style->d()->brush != r->d()->context->state.fillStyle) {
r->d()->context->state.fillStyle = *style->d()->brush;
r->d()->context->buffer()->setFillStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
r->d()->context->m_fillStyle.set(scope.engine, value);
r->d()->context->state.fillPatternRepeatX = style->d()->patternRepeatX;
r->d()->context->state.fillPatternRepeatY = style->d()->patternRepeatY;
@ -1501,9 +1505,9 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
r->d()->context->m_strokeStyle.set(scope.engine, value);
} else {
QV4::Scoped<QQuickContext2DStyle> style(scope, value->as<QQuickContext2DStyle>());
if (style && style->d()->brush != r->d()->context->state.strokeStyle) {
r->d()->context->state.strokeStyle = style->d()->brush;
r->d()->context->buffer()->setStrokeStyle(style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
if (style && *style->d()->brush != r->d()->context->state.strokeStyle) {
r->d()->context->state.strokeStyle = *style->d()->brush;
r->d()->context->buffer()->setStrokeStyle(*style->d()->brush, style->d()->patternRepeatX, style->d()->patternRepeatY);
r->d()->context->m_strokeStyle.set(scope.engine, value);
r->d()->context->state.strokePatternRepeatX = style->d()->patternRepeatX;
r->d()->context->state.strokePatternRepeatY = style->d()->patternRepeatY;
@ -1561,7 +1565,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
*gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
return gradient.asReturnedValue();
}
@ -1612,7 +1616,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
*gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
return gradient.asReturnedValue();
}
@ -1655,7 +1659,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
gradient->d()->brush = QConicalGradient(x, y, angle);
*gradient->d()->brush = QConicalGradient(x, y, angle);
return gradient.asReturnedValue();
}
@ -1720,7 +1724,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
style = static_cast<Qt::BrushStyle>(patternMode);
}
pattern->d()->brush = QBrush(color, style);
*pattern->d()->brush = QBrush(color, style);
} else {
QImage patternTexture;
@ -1728,14 +1732,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
patternTexture = pixelData->d()->image;
patternTexture = *pixelData->d()->image;
}
} else {
patternTexture = r->d()->context->createPixmap(QUrl(ctx->args()[0].toQStringNoThrow()))->image();
}
if (!patternTexture.isNull()) {
pattern->d()->brush.setTextureImage(patternTexture);
pattern->d()->brush->setTextureImage(patternTexture);
QString repetition = ctx->args()[1].toQStringNoThrow();
if (repetition == QLatin1String("repeat") || repetition.isEmpty()) {
@ -2925,8 +2929,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
if (!!imageData) {
QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pix && !pix->d()->image.isNull()) {
pixmap.adopt(new QQuickCanvasPixmap(pix->d()->image));
if (pix && !pix->d()->image->isNull()) {
pixmap.adopt(new QQuickCanvasPixmap(*pix->d()->image));
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
@ -3034,7 +3038,7 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(QV4::CallContext
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (!r)
return QV4::Encode(0);
return QV4::Encode(r->d()->image.width());
return QV4::Encode(r->d()->image->width());
}
/*!
@ -3050,7 +3054,7 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(QV4::CallContex
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (!r)
return QV4::Encode(0);
return QV4::Encode(r->d()->image.height());
return QV4::Encode(r->d()->image->height());
}
/*!
@ -3088,10 +3092,10 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::CallContext
{
QV4::Scope scope(ctx);
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, ctx->thisObject().as<QQuickJSContext2DPixelData>());
if (!r || r->d()->image.isNull())
if (!r || r->d()->image->isNull())
return QV4::Encode::undefined();
return QV4::Encode(r->d()->image.width() * r->d()->image.height() * 4);
return QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4);
}
QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
@ -3101,13 +3105,13 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m,
QV4::Scope scope(v4);
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<const QQuickJSContext2DPixelData *>(m));
if (index < static_cast<quint32>(r->d()->image.width() * r->d()->image.height() * 4)) {
if (index < static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4)) {
if (hasProperty)
*hasProperty = true;
const quint32 w = r->d()->image.width();
const quint32 w = r->d()->image->width();
const quint32 row = (index / 4) / w;
const quint32 col = (index / 4) % w;
const QRgb* pixel = reinterpret_cast<const QRgb*>(r->d()->image.constScanLine(row));
const QRgb* pixel = reinterpret_cast<const QRgb*>(r->d()->image->constScanLine(row));
pixel += col;
switch (index % 4) {
case 0:
@ -3136,12 +3140,12 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
const int v = value.toInt32();
if (r && index < static_cast<quint32>(r->d()->image.width() * r->d()->image.height() * 4) && v >= 0 && v <= 255) {
const quint32 w = r->d()->image.width();
if (r && index < static_cast<quint32>(r->d()->image->width() * r->d()->image->height() * 4) && v >= 0 && v <= 255) {
const quint32 w = r->d()->image->width();
const quint32 row = (index / 4) / w;
const quint32 col = (index / 4) % w;
QRgb* pixel = reinterpret_cast<QRgb*>(r->d()->image.scanLine(row));
QRgb* pixel = reinterpret_cast<QRgb*>(r->d()->image->scanLine(row));
pixel += col;
switch (index % 4) {
case 0:
@ -3192,8 +3196,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::CallC
if (!!imgData) {
QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pa) {
qreal w = pa->d()->image.width();
qreal h = pa->d()->image.height();
qreal w = pa->d()->image->width();
qreal h = pa->d()->image->height();
return qt_create_image_data(w, h, scope.engine, QImage());
}
} else if (arg0->isString()) {
@ -3271,8 +3275,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pixelArray) {
w = pixelArray->d()->image.width();
h = pixelArray->d()->image.height();
w = pixelArray->d()->image->width();
h = pixelArray->d()->image->height();
if (ctx->argc() == 7) {
dirtyX = ctx->args()[3].toNumber();
@ -3321,7 +3325,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
dirtyHeight = h;
}
QImage image = pixelArray->d()->image.copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
r->d()->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
}
return ctx->thisObject().asReturnedValue();
@ -3356,9 +3360,9 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallCo
if (ctx->argc() == 2) {
if (!style->d()->brush.gradient())
if (!style->d()->brush->gradient())
V4THROW_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
QGradient gradient = *(style->d()->brush.gradient());
QGradient gradient = *(style->d()->brush->gradient());
qreal pos = ctx->args()[0].toNumber();
QColor color;
@ -3376,7 +3380,7 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallCo
} else {
V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
}
style->d()->brush = gradient;
*style->d()->brush = gradient;
}
return ctx->thisObject().asReturnedValue();

View File

@ -7264,7 +7264,7 @@ struct WeakReferenceSentinel : public Object {
}
~WeakReferenceSentinel() {
void destroy() {
*resultPtr = weakRef->isNullOrUndefined();
}