From 45f7120d42f628e86ae2bf3bd2789fdb190490e0 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 8 May 2014 22:27:23 +0200 Subject: [PATCH] Convert regexps Change-Id: I5b62a265a7ce363a16b1e14ae93cadbb1ab0cb5b Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 10 +++-- src/qml/jsruntime/qv4engine_p.h | 2 +- src/qml/jsruntime/qv4functionobject.cpp | 3 +- src/qml/jsruntime/qv4object.cpp | 1 - src/qml/jsruntime/qv4object_p.h | 2 +- src/qml/jsruntime/qv4regexp.cpp | 39 ++++++++--------- src/qml/jsruntime/qv4regexp_p.h | 75 ++++++++++++++++----------------- src/qml/jsruntime/qv4regexpobject.cpp | 56 +++++++++++++----------- src/qml/jsruntime/qv4regexpobject_p.h | 24 +++++++---- src/qml/jsruntime/qv4scopedvalue_p.h | 14 ++++++ src/qml/jsruntime/qv4script.cpp | 28 ++++++------ src/qml/qml/qqmlcomponent.cpp | 37 ++++++++-------- src/qml/qml/qqmllocale.cpp | 2 +- src/qml/qml/qqmllocale_p.h | 16 +++---- 14 files changed, 167 insertions(+), 142 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2f64ce4..84c522e 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -302,8 +302,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index); Q_ASSERT(index == FunctionObject::Index_ProtoConstructor); - RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype)); - regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype); + Scoped regExpPrototype(scope, new (this) RegExpPrototype::Data(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype))); + regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype.getPointer()); regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayIndex); regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index); @@ -592,13 +592,15 @@ Returned *ExecutionEngine::newRegExpObject(const QString &pattern, Returned *ExecutionEngine::newRegExpObject(RegExp *re, bool global) { - RegExpObject *object = new (memoryManager) RegExpObject(this, re, global); + Scope scope(this); + Scoped object(scope, new (this) RegExpObject::Data(this, re, global)); return object->asReturned(); } Returned *ExecutionEngine::newRegExpObject(const QRegExp &re) { - RegExpObject *object = new (memoryManager) RegExpObject(this, re); + Scope scope(this); + Scoped object(scope, new (this) RegExpObject::Data(this, re)); return object->asReturned(); } diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 8d8527e..12434db 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -112,7 +112,7 @@ struct IdentifierTable; struct InternalClass; struct InternalClassPool; class MultiplyWrappedQObjectMap; -class RegExp; +struct RegExp; class RegExpCache; struct QmlExtensions; struct Exception; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 791ff0f..38b2dcb 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -169,6 +169,7 @@ void FunctionObject::init(String *n, bool createProto) d()->needsActivation = true; d()->strictMode = false; + memberData().ensureIndex(s.engine, Index_Prototype); if (createProto) { Scoped proto(s, scope()->d()->engine->newObject(scope()->d()->engine->protoClass)); proto->memberData()[Index_ProtoConstructor] = this->asReturnedValue(); @@ -178,7 +179,7 @@ void FunctionObject::init(String *n, bool createProto) } ScopedValue v(s, n); - defineReadonlyProperty(scope()->d()->engine->id_name, v); + defineReadonlyProperty(s.engine->id_name, v); } ReturnedValue FunctionObject::name() diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 9abfb25..235519b 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -90,7 +90,6 @@ Object::Object(InternalClass *ic) { Q_ASSERT(internalClass()->vtable != &Managed::static_vtbl); - Q_ASSERT(!memberData().d()); if (internalClass()->size) { Scope scope(engine()); ScopedObject protectThis(scope, this); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 4ba27cc..b98c771 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -125,7 +125,7 @@ struct Q_QML_EXPORT Object: Managed { }; Members &memberData() { return d()->memberData; } - Members memberData() const { return d()->memberData; } + const Members &memberData() const { return d()->memberData; } const ArrayData *arrayData() const { return d()->arrayData; } ArrayData *arrayData() { return d()->arrayData; } void setArrayData(ArrayData *a) { d()->arrayData = a; } diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 1207500..08025e0 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -49,7 +49,7 @@ RegExpCache::~RegExpCache() { for (RegExpCache::Iterator it = begin(), e = end(); it != e; ++it) - it.value()->d()->cache = 0; + it.value()->cache = 0; clear(); } @@ -70,62 +70,59 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets) return JSC::Yarr::interpret(byteCode().get(), s.characters16(), string.length(), start, matchOffsets); } -RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline) +RegExp::Data* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline) { RegExpCacheKey key(pattern, ignoreCase, multiline); RegExpCache *cache = engine->regExpCache; if (cache) { - if (RegExp *result = cache->value(key)) + if (RegExp::Data *result = cache->value(key)) return result; } - RegExp *result = new (engine->memoryManager) RegExp(engine, pattern, ignoreCase, multiline); + RegExp::Data *result = new (engine) RegExp::Data(engine, pattern, ignoreCase, multiline); if (!cache) cache = engine->regExpCache = new RegExpCache; - result->d()->cache = cache; + result->cache = cache; cache->insert(key, result); return result; } -RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline) - : Managed(engine->regExpValueClass) +RegExp::Data::Data(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline) + : Managed::Data(engine->regExpValueClass) + , pattern(pattern) + , ignoreCase(ignoreCase) + , multiLine(multiline) { - d()->pattern = pattern; - d()->cache = 0; - d()->ignoreCase = ignoreCase; - d()->multiLine = multiline; - - if (!engine) - return; + setVTable(staticVTable()); const char* error = 0; JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiline, &error); if (error) return; - d()->subPatternCount = yarrPattern.m_numSubpatterns; - d()->byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator); + subPatternCount = yarrPattern.m_numSubpatterns; + byteCode = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator); #if ENABLE(YARR_JIT) if (!yarrPattern.m_containsBackreferences && engine->iselFactory->jitCompileRegexps()) { JSC::JSGlobalData dummy(engine->regExpAllocator); - JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, d()->jitCode); + JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, jitCode); } #endif } -RegExp::~RegExp() +RegExp::Data::~Data() { - if (cache()) { + if (cache) { RegExpCacheKey key(this); - cache()->remove(key); + cache->remove(key); } } void RegExp::destroy(Managed *that) { - static_cast(that)->~RegExp(); + static_cast(that)->d()->~Data(); } void RegExp::markObjects(Managed *that, ExecutionEngine *e) diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h index 983fd03..29f759f 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -62,38 +62,13 @@ QT_BEGIN_NAMESPACE namespace QV4 { struct ExecutionEngine; +struct RegExpCacheKey; -struct RegExpCacheKey -{ - RegExpCacheKey(const QString &pattern, bool ignoreCase, bool multiLine) - : pattern(pattern) - , ignoreCase(ignoreCase) - , multiLine(multiLine) - { } - explicit inline RegExpCacheKey(const RegExp *re); - - bool operator==(const RegExpCacheKey &other) const - { return pattern == other.pattern && ignoreCase == other.ignoreCase && multiLine == other.multiLine; } - bool operator!=(const RegExpCacheKey &other) const - { return !operator==(other); } - - QString pattern; - uint ignoreCase : 1; - uint multiLine : 1; -}; - -inline uint qHash(const RegExpCacheKey& key, uint seed = 0) Q_DECL_NOTHROW -{ return qHash(key.pattern, seed); } - -class RegExpCache : public QHash -{ -public: - ~RegExpCache(); -}; - -class RegExp : public Managed +struct RegExp : public Managed { struct Data : Managed::Data { + Data(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline); + ~Data(); QString pattern; OwnPtr byteCode; #if ENABLE(YARR_JIT) @@ -129,8 +104,7 @@ class RegExp : public Managed bool ignoreCase() const { return d()->ignoreCase; } bool multiLine() const { return d()->multiLine; } - static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false); - ~RegExp(); + static RegExp::Data* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false); bool isValid() const { return d()->byteCode.get(); } @@ -141,19 +115,44 @@ class RegExp : public Managed static void destroy(Managed *that); static void markObjects(Managed *that, QV4::ExecutionEngine *e); -private: friend class RegExpCache; - Q_DISABLE_COPY(RegExp); - RegExp(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline); +}; + +struct RegExpCacheKey +{ + RegExpCacheKey(const QString &pattern, bool ignoreCase, bool multiLine) + : pattern(pattern) + , ignoreCase(ignoreCase) + , multiLine(multiLine) + { } + explicit inline RegExpCacheKey(const RegExp::Data *re); + + bool operator==(const RegExpCacheKey &other) const + { return pattern == other.pattern && ignoreCase == other.ignoreCase && multiLine == other.multiLine; } + bool operator!=(const RegExpCacheKey &other) const + { return !operator==(other); } + QString pattern; + uint ignoreCase : 1; + uint multiLine : 1; }; -inline RegExpCacheKey::RegExpCacheKey(const RegExp *re) - : pattern(re->pattern()) - , ignoreCase(re->ignoreCase()) - , multiLine(re->multiLine()) +inline RegExpCacheKey::RegExpCacheKey(const RegExp::Data *re) + : pattern(re->pattern) + , ignoreCase(re->ignoreCase) + , multiLine(re->multiLine) {} +inline uint qHash(const RegExpCacheKey& key, uint seed = 0) Q_DECL_NOTHROW +{ return qHash(key.pattern, seed); } + +class RegExpCache : public QHash +{ +public: + ~RegExpCache(); +}; + + } diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 2406fa2..f7135d9 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -70,32 +70,42 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyn using namespace QV4; DEFINE_OBJECT_VTABLE(RegExpObject); +DEFINE_OBJECT_VTABLE(RegExpPrototype); -RegExpObject::RegExpObject(InternalClass *ic) - : Object(ic) +RegExpObject::Data::Data(InternalClass *ic) + : Object::Data(ic) { - d()->value = RegExp::create(ic->engine, QString(), false, false); - d()->global = false; - Q_ASSERT(internalClass()->vtable == staticVTable()); - init(ic->engine); + setVTable(staticVTable()); + + Scope scope(ic->engine); + Scoped o(scope, this); + o->d()->value = reinterpret_cast(RegExp::create(ic->engine, QString(), false, false)); + o->d()->global = false; + o->init(ic->engine); } -RegExpObject::RegExpObject(ExecutionEngine *engine, RegExp *value, bool global) - : Object(engine->regExpClass) +RegExpObject::Data::Data(ExecutionEngine *engine, RegExp *value, bool global) + : Object::Data(engine->regExpClass) + , value(value) + , global(global) { - d()->value = value; - d()->global = global; - init(engine); + setVTable(staticVTable()); + + Scope scope(engine); + Scoped o(scope, this); + o->init(engine); } // Converts a QRegExp to a JS RegExp. // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. -RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re) - : Object(engine->regExpClass) +RegExpObject::Data::Data(ExecutionEngine *engine, const QRegExp &re) + : Object::Data(engine->regExpClass) { - d()->value = 0; - d()->global = false; + setVTable(staticVTable()); + + value = 0; + global = false; // Convert the pattern to a ECMAScript pattern. QString pattern = QT_PREPEND_NAMESPACE(qt_regexp_toCanonical)(re.pattern(), re.patternSyntax()); @@ -135,17 +145,15 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re) } Scope scope(engine); - ScopedObject protectThis(scope, this); + Scoped o(scope, this); - d()->value = RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false); + o->d()->value = reinterpret_cast(RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false)); - init(engine); + o->init(engine); } void RegExpObject::init(ExecutionEngine *engine) { - setVTable(staticVTable()); - Scope scope(engine); ScopedObject protectThis(scope, this); @@ -256,8 +264,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) if (!f->isUndefined()) return ctx->throwTypeError(); - Scoped newRe(scope, re->value()); - return Encode(ctx->d()->engine->newRegExpObject(newRe, re->global())); + return Encode(ctx->d()->engine->newRegExpObject(re->value(), re->global())); } QString pattern; @@ -287,7 +294,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) } } - Scoped regexp(scope, RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine)); + RegExp *regexp = reinterpret_cast(RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine)); if (!regexp->isValid()) return ctx->throwSyntaxError(QStringLiteral("Invalid regular expression")); @@ -312,10 +319,11 @@ void RegExpCtor::markObjects(Managed *that, ExecutionEngine *e) FunctionObject::markObjects(that, e); } -void RegExpPrototype::init(ExecutionEngine *engine, Object *ctor) +void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor) { Scope scope(engine); ScopedObject o(scope); + ScopedObject ctor(scope, constructor); ctor->defineReadonlyProperty(engine->id_prototype, (o = this)); ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(2)); diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index f6d2f66..90ff8ca 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -63,15 +63,17 @@ QT_BEGIN_NAMESPACE namespace QV4 { -class RegExp; - struct RegExpObject: Object { struct Data : Object::Data { - RegExp* value; + Data(ExecutionEngine *engine, RegExp *value, bool global); + Data(ExecutionEngine *engine, const QRegExp &re); + Data(InternalClass *ic); + + RegExp *value; bool global; }; struct { - RegExp* value; + RegExp *value; bool global; } __data; @@ -93,9 +95,6 @@ struct RegExpObject: Object { RegExp *value() const { return d()->value; } bool global() const { return d()->global; } - RegExpObject(ExecutionEngine *engine, RegExp *value, bool global); - RegExpObject(ExecutionEngine *engine, const QRegExp &re); - void init(ExecutionEngine *engine); Property *lastIndexProperty(ExecutionContext *ctx); @@ -105,7 +104,6 @@ struct RegExpObject: Object { uint flags() const; protected: - RegExpObject(InternalClass *ic); static void markObjects(Managed *that, ExecutionEngine *e); }; @@ -140,7 +138,15 @@ struct RegExpCtor: FunctionObject struct RegExpPrototype: RegExpObject { - RegExpPrototype(InternalClass *ic): RegExpObject(ic) {} + struct Data : RegExpObject::Data + { + Data(InternalClass *ic): RegExpObject::Data(ic) + { + setVTable(staticVTable()); + } + }; + V4_OBJECT + void init(ExecutionEngine *engine, Object *ctor); static ReturnedValue method_exec(CallContext *ctx); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 5a7852f..6045ea5 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -117,6 +117,15 @@ struct ScopedValue #endif } + ScopedValue(const Scope &scope, HeapObject *o) + { + ptr = scope.engine->jsStackTop++; + ptr->m = reinterpret_cast(o); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + ScopedValue(const Scope &scope, Managed *m) { ptr = scope.engine->jsStackTop++; @@ -150,6 +159,11 @@ struct ScopedValue return *this; } + ScopedValue &operator=(HeapObject *o) { + ptr->m = reinterpret_cast(o); + return *this; + } + ScopedValue &operator=(Managed *m) { ptr->val = m->asReturnedValue(); return *this; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 635115f..c397922 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -167,6 +167,17 @@ DEFINE_OBJECT_VTABLE(QmlBindingWrapper); struct CompilationUnitHolder : public Object { struct Data : Object::Data { + Data(ExecutionEngine *engine, CompiledData::CompilationUnit *unit) + : Object::Data(engine) + , unit(unit) + { + unit->ref(); + setVTable(staticVTable()); + } + ~Data() + { + unit->deref(); + } QV4::CompiledData::CompilationUnit *unit; }; struct { @@ -175,21 +186,10 @@ struct CompilationUnitHolder : public Object V4_OBJECT - CompilationUnitHolder(ExecutionEngine *engine, CompiledData::CompilationUnit *unit) - : Object(engine) - { - d()->unit = unit; - d()->unit->ref(); - setVTable(staticVTable()); - } - ~CompilationUnitHolder() - { - d()->unit->deref(); - } static void destroy(Managed *that) { - static_cast(that)->~CompilationUnitHolder(); + static_cast(that)->d()->~Data(); } }; @@ -206,7 +206,7 @@ Script::Script(ExecutionEngine *v4, Object *qml, CompiledData::CompilationUnit * vmFunction = compilationUnit->linkToEngine(v4); Q_ASSERT(vmFunction); Scope valueScope(v4); - ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit)); + ScopedObject holder(valueScope, new (v4) CompilationUnitHolder::Data(v4, compilationUnit)); compilationUnitHolder = holder.asReturnedValue(); } else vmFunction = 0; @@ -278,7 +278,7 @@ void Script::parse() isel->setUseFastLookups(false); QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile(); vmFunction = compilationUnit->linkToEngine(v4); - ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit)); + ScopedObject holder(valueScope, new (v4) CompilationUnitHolder::Data(v4, compilationUnit)); compilationUnitHolder = holder.asReturnedValue(); } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index ce9771f..716aa31 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1074,9 +1074,10 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, class QQmlComponentIncubator; -class QmlIncubatorObject : public QV4::Object +struct QmlIncubatorObject : public QV4::Object { struct Data : QV4::Object::Data { + Data(QV8Engine *engine, QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous); QScopedPointer incubator; QV8Engine *v8; QPointer parent; @@ -1094,8 +1095,6 @@ class QmlIncubatorObject : public QV4::Object } __data; V4_OBJECT -public: - QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous); static QV4::ReturnedValue method_get_statusChanged(QV4::CallContext *ctx); static QV4::ReturnedValue method_set_statusChanged(QV4::CallContext *ctx); @@ -1115,20 +1114,24 @@ DEFINE_OBJECT_VTABLE(QmlIncubatorObject); class QQmlComponentIncubator : public QQmlIncubator { public: - QQmlComponentIncubator(QmlIncubatorObject *inc, IncubationMode mode) + QQmlComponentIncubator(QmlIncubatorObject::Data *inc, IncubationMode mode) : QQmlIncubator(mode) , incubatorObject(inc) {} virtual void statusChanged(Status s) { - incubatorObject->statusChanged(s); + QV4::Scope scope(incubatorObject->internalClass->engine); + QV4::Scoped i(scope, incubatorObject); + i->statusChanged(s); } virtual void setInitialState(QObject *o) { - incubatorObject->setInitialState(o); + QV4::Scope scope(incubatorObject->internalClass->engine); + QV4::Scoped i(scope, incubatorObject); + i->setInitialState(o); } - QmlIncubatorObject *incubatorObject; + QmlIncubatorObject::Data *incubatorObject; }; @@ -1364,7 +1367,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) QQmlComponentExtension *e = componentExtension(args->engine()); - QV4::Scoped r(scope, new (v4->memoryManager) QmlIncubatorObject(args->engine(), mode)); + QV4::Scoped r(scope, new (v4) QmlIncubatorObject::Data(args->engine(), mode)); QV4::ScopedObject p(scope, e->incubationProto.value()); r->setPrototype(p.getPointer()); @@ -1479,16 +1482,16 @@ QQmlComponentExtension::~QQmlComponentExtension() { } -QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::IncubationMode m) - : Object(QV8Engine::getV4(engine)) +QmlIncubatorObject::Data::Data(QV8Engine *engine, QQmlIncubator::IncubationMode m) + : Object::Data(QV8Engine::getV4(engine)) + , v8(engine) + , valuemap(QV4::Primitive::undefinedValue()) + , qmlGlobal(QV4::Primitive::undefinedValue()) + , statusChanged(QV4::Primitive::undefinedValue()) { setVTable(staticVTable()); - d()->incubator.reset(new QQmlComponentIncubator(this, m)); - d()->v8 = engine; - d()->valuemap = QV4::Primitive::undefinedValue(); - d()->qmlGlobal = QV4::Primitive::undefinedValue(); - d()->statusChanged = QV4::Primitive::undefinedValue(); + incubator.reset(new QQmlComponentIncubator(this, m)); } void QmlIncubatorObject::setInitialState(QObject *o) @@ -1510,9 +1513,7 @@ void QmlIncubatorObject::setInitialState(QObject *o) void QmlIncubatorObject::destroy(Managed *that) { - QmlIncubatorObject *o = that->as(); - Q_ASSERT(o); - o->~QmlIncubatorObject(); + that->as()->d()->~Data(); } void QmlIncubatorObject::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e) diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index c66b592..7687c17 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -814,7 +814,7 @@ QV4::ReturnedValue QQmlLocale::wrap(QV8Engine *engine, const QLocale &locale) QV8LocaleDataDeletable *d = localeV8Data(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); - QV4::Scoped wrapper(scope, new (v4->memoryManager) QQmlLocaleData(v4)); + QV4::Scoped wrapper(scope, new (v4) QQmlLocaleData::Data(v4)); wrapper->d()->locale = locale; QV4::ScopedObject p(scope, d->prototype.value()); wrapper->setPrototype(p.getPointer()); diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 02877d7..d5812ef 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -129,9 +129,14 @@ private: static QV4::ReturnedValue method_localeCompare(QV4::CallContext *ctx); }; -class QQmlLocaleData : public QV4::Object +struct QQmlLocaleData : public QV4::Object { - struct Data : QV4::Object::Data { + struct Data : Object::Data { + Data(QV4::ExecutionEngine *engine) + : Object::Data(engine) + { + setVTable(staticVTable()); + } QLocale locale; }; struct { @@ -139,13 +144,6 @@ class QQmlLocaleData : public QV4::Object } __data; V4_OBJECT -public: - QQmlLocaleData(QV4::ExecutionEngine *engine) - : QV4::Object(engine) - { - setVTable(staticVTable()); - } - static QLocale *getThisLocale(QV4::CallContext *ctx) { QQmlLocaleData *thisObject = ctx->d()->callData->thisObject.asObject()->as(); -- 2.7.4