Convert regexps
authorLars Knoll <lars.knoll@digia.com>
Thu, 8 May 2014 20:27:23 +0000 (22:27 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 22 Jul 2014 11:49:17 +0000 (13:49 +0200)
Change-Id: I5b62a265a7ce363a16b1e14ae93cadbb1ab0cb5b
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
14 files changed:
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4regexp.cpp
src/qml/jsruntime/qv4regexp_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4regexpobject_p.h
src/qml/jsruntime/qv4scopedvalue_p.h
src/qml/jsruntime/qv4script.cpp
src/qml/qml/qqmlcomponent.cpp
src/qml/qml/qqmllocale.cpp
src/qml/qml/qqmllocale_p.h

index 2f64ce4..84c522e 100644 (file)
@@ -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> 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<RegExpObject> *ExecutionEngine::newRegExpObject(const QString &pattern,
 
 Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExp *re, bool global)
 {
-    RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
+    Scope scope(this);
+    Scoped<RegExpObject> object(scope, new (this) RegExpObject::Data(this, re, global));
     return object->asReturned<RegExpObject>();
 }
 
 Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QRegExp &re)
 {
-    RegExpObject *object = new (memoryManager) RegExpObject(this, re);
+    Scope scope(this);
+    Scoped<RegExpObject> object(scope, new (this) RegExpObject::Data(this, re));
     return object->asReturned<RegExpObject>();
 }
 
index 8d8527e..12434db 100644 (file)
@@ -112,7 +112,7 @@ struct IdentifierTable;
 struct InternalClass;
 struct InternalClassPool;
 class MultiplyWrappedQObjectMap;
-class RegExp;
+struct RegExp;
 class RegExpCache;
 struct QmlExtensions;
 struct Exception;
index 791ff0f..38b2dcb 100644 (file)
@@ -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<Object> 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()
index 9abfb25..235519b 100644 (file)
@@ -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);
index 4ba27cc..b98c771 100644 (file)
@@ -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; }
index 1207500..08025e0 100644 (file)
@@ -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<RegExp*>(that)->~RegExp();
+    static_cast<RegExp*>(that)->d()->~Data();
 }
 
 void RegExp::markObjects(Managed *that, ExecutionEngine *e)
index 983fd03..29f759f 100644 (file)
@@ -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<RegExpCacheKey, RegExp*>
-{
-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<JSC::Yarr::BytecodePattern> 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<RegExpCacheKey, RegExp::Data *>
+{
+public:
+    ~RegExpCache();
+};
+
+
 
 }
 
index 2406fa2..f7135d9 100644 (file)
@@ -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<RegExpObject> o(scope, this);
+    o->d()->value = reinterpret_cast<RegExp *>(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<RegExpObject> 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<RegExpObject> o(scope, this);
 
-    d()->value = RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false);
+    o->d()->value = reinterpret_cast<RegExp *>(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<RegExp> 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> regexp(scope, RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine));
+    RegExp *regexp = reinterpret_cast<RegExp *>(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));
index f6d2f66..90ff8ca 100644 (file)
@@ -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 {
-        RegExpvalue;
+        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);
index 5a7852f..6045ea5 100644 (file)
@@ -117,6 +117,15 @@ struct ScopedValue
 #endif
     }
 
+    ScopedValue(const Scope &scope, HeapObject *o)
+    {
+        ptr = scope.engine->jsStackTop++;
+        ptr->m = reinterpret_cast<Managed *>(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<Managed *>(o);
+        return *this;
+    }
+
     ScopedValue &operator=(Managed *m) {
         ptr->val = m->asReturnedValue();
         return *this;
index 635115f..c397922 100644 (file)
@@ -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<CompilationUnitHolder*>(that)->~CompilationUnitHolder();
+        static_cast<CompilationUnitHolder*>(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();
     }
 
index ce9771f..716aa31 100644 (file)
@@ -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<QQmlComponentIncubator> incubator;
         QV8Engine *v8;
         QPointer<QObject> 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<QmlIncubatorObject> i(scope, incubatorObject);
+        i->statusChanged(s);
     }
 
     virtual void setInitialState(QObject *o) {
-        incubatorObject->setInitialState(o);
+        QV4::Scope scope(incubatorObject->internalClass->engine);
+        QV4::Scoped<QmlIncubatorObject> 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<QmlIncubatorObject> r(scope, new (v4->memoryManager) QmlIncubatorObject(args->engine(), mode));
+    QV4::Scoped<QmlIncubatorObject> 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<QmlIncubatorObject>();
-    Q_ASSERT(o);
-    o->~QmlIncubatorObject();
+    that->as<QmlIncubatorObject>()->d()->~Data();
 }
 
 void QmlIncubatorObject::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
index c66b592..7687c17 100644 (file)
@@ -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<QQmlLocaleData> wrapper(scope, new (v4->memoryManager) QQmlLocaleData(v4));
+    QV4::Scoped<QQmlLocaleData> wrapper(scope, new (v4) QQmlLocaleData::Data(v4));
     wrapper->d()->locale = locale;
     QV4::ScopedObject p(scope, d->prototype.value());
     wrapper->setPrototype(p.getPointer());
index 02877d7..d5812ef 100644 (file)
@@ -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<QQmlLocaleData>();