Move Managed::type and some flags into the vtable
authorLars Knoll <lars.knoll@digia.com>
Fri, 6 Dec 2013 09:28:50 +0000 (10:28 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 3 Jan 2014 16:09:16 +0000 (17:09 +0100)
Move the type flag into the vtable to free up these
bits in the Managed class, and not have to set them
at object construction time.

As we often need to know whether a Managed object is a
Object, FunctionObject or String, add some bitflags to test
for these to the vtable.

Change-Id: I7d08ca044544debb307b55f124f34cb086ad9e84
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
32 files changed:
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4argumentsobject_p.h
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4dateobject.cpp
src/qml/jsruntime/qv4dateobject_p.h
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4errorobject.cpp
src/qml/jsruntime/qv4errorobject_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4functionobject_p.h
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4jsonobject_p.h
src/qml/jsruntime/qv4managed.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4mathobject.cpp
src/qml/jsruntime/qv4mathobject_p.h
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4objectiterator_p.h
src/qml/jsruntime/qv4objectproto.cpp
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/qv4sequenceobject.cpp
src/qml/jsruntime/qv4string.cpp
src/qml/jsruntime/qv4string_p.h
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4stringobject_p.h
src/qml/jsruntime/qv4value_p.h
src/qml/qml/qqmllocale.cpp

index 629c255..df08b5a 100644 (file)
@@ -51,7 +51,6 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
     , context(context)
     , fullyCreated(false)
 {
-    type = Type_ArgumentsObject;
     flags &= ~SimpleArray;
 
     ExecutionEngine *v4 = context->engine;
index d306fae..b300dcf 100644 (file)
@@ -77,6 +77,7 @@ struct ArgumentsSetterFunction: FunctionObject
 
 struct ArgumentsObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(ArgumentsObject)
     CallContext *context;
     bool fullyCreated;
     QVector<SafeValue> mappedArguments;
index 05a0e66..f5d8106 100644 (file)
@@ -53,6 +53,13 @@ using namespace QV4;
 
 const ManagedVTable ExecutionContext::static_vtbl =
 {
+    ExecutionContext::IsExecutionContext,
+    ExecutionContext::IsString,
+    ExecutionContext::IsObject,
+    ExecutionContext::IsFunctionObject,
+    ExecutionContext::IsErrorObject,
+    0,
+    ExecutionContext::MyType,
     call,
     construct,
     markObjects,
index 4eb89ad..851f024 100644 (file)
@@ -70,6 +70,10 @@ struct WithContext;
 struct Q_QML_EXPORT ExecutionContext : public Managed
 {
     Q_MANAGED
+    Q_MANAGED_TYPE(ExecutionContext)
+    enum {
+        IsExecutionContext = true
+    };
 
     enum ContextType {
         Type_GlobalContext = 0x1,
index 5d0c8cc..2b6aa21 100644 (file)
@@ -647,7 +647,6 @@ DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
     : Object(engine->dateClass)
 {
     setVTable(&static_vtbl);
-    type = Type_DateObject;
     value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
 }
 
index 9c451dd..244553b 100644 (file)
@@ -53,9 +53,9 @@ namespace QV4 {
 
 struct DateObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(DateObject)
     SafeValue value;
     DateObject(ExecutionEngine *engine, const ValueRef date): Object(engine->dateClass) {
-        type = Type_DateObject;
         value = date;
     }
     DateObject(ExecutionEngine *engine, const QDateTime &value);
@@ -64,8 +64,7 @@ struct DateObject: Object {
 
 protected:
     DateObject(InternalClass *ic): Object(ic) {
-        setVTable(&static_vtbl);
-        type = Type_DateObject;
+        Q_ASSERT(internalClass->vtable == &static_vtbl);
         value = Primitive::fromDouble(qSNaN());
     }
 };
index f55b47c..384254f 100644 (file)
@@ -249,16 +249,16 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
 
     initRootContext();
 
-    StringPrototype *stringPrototype = new (memoryManager) StringPrototype(objectClass);
+    StringPrototype *stringPrototype = new (memoryManager) StringPrototype(InternalClass::create(this, &StringPrototype::static_vtbl, objectPrototype));
     stringObjectClass = InternalClass::create(this, &String::static_vtbl, stringPrototype);
 
-    NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(objectClass);
+    NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(InternalClass::create(this, &NumberPrototype::static_vtbl, objectPrototype));
     numberClass = InternalClass::create(this, &NumberObject::static_vtbl, numberPrototype);
 
-    BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(objectClass);
+    BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(InternalClass::create(this, &BooleanPrototype::static_vtbl, objectPrototype));
     booleanClass = InternalClass::create(this, &BooleanObject::static_vtbl, booleanPrototype);
 
-    DatePrototype *datePrototype = new (memoryManager) DatePrototype(objectClass);
+    DatePrototype *datePrototype = new (memoryManager) DatePrototype(InternalClass::create(this, &DatePrototype::static_vtbl, objectPrototype));
     dateClass = InternalClass::create(this, &DateObject::static_vtbl, datePrototype);
 
     FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(InternalClass::create(this, &FunctionPrototype::static_vtbl, objectPrototype));
@@ -269,14 +269,14 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
     protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
     Q_ASSERT(index == FunctionObject::Index_ProtoConstructor);
 
-    RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(objectClass);
+    RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(InternalClass::create(this, &RegExpPrototype::static_vtbl, objectPrototype));
     regExpClass = InternalClass::create(this, &RegExpObject::static_vtbl, regExpPrototype);
     regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
     Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
     regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
     Q_ASSERT(index == RegExpObject::Index_ArrayInput);
 
-    ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(objectClass);
+    ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(InternalClass::create(this, &ErrorObject::static_vtbl, objectPrototype));
     errorClass = InternalClass::create(this, &ErrorObject::static_vtbl, errorPrototype);
     EvalErrorPrototype *evalErrorPrototype = new (memoryManager) EvalErrorPrototype(errorClass);
     evalErrorClass = InternalClass::create(this, &EvalErrorObject::static_vtbl, evalErrorPrototype);
@@ -357,8 +357,8 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
     globalObject->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
     globalObject->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
     ScopedObject o(scope);
-    globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(this)));
-    globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(this)));
+    globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(QV4::InternalClass::create(this, &MathObject::static_vtbl, objectPrototype))));
+    globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(QV4::InternalClass::create(this, &JsonObject::static_vtbl, objectPrototype))));
 
     globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
     globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
index cf5c06d..f5d21b2 100644 (file)
@@ -76,8 +76,6 @@ ErrorObject::ErrorObject(InternalClass *ic)
     : Object(ic)
     , stack(0)
 {
-    type = Type_ErrorObject;
-
     Scope scope(engine());
     ScopedValue protectThis(scope, this);
 
@@ -89,7 +87,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t)
     : Object(ic)
     , stack(0)
 {
-    type = Type_ErrorObject;
     subtype = t;
 
     Scope scope(engine());
@@ -113,7 +110,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorObject:
     : Object(ic)
     , stack(0)
 {
-    type = Type_ErrorObject;
     subtype = t;
 
     Scope scope(engine());
@@ -137,7 +133,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin
     : Object(ic)
     , stack(0)
 {
-    type = Type_ErrorObject;
     subtype = t;
 
     Scope scope(engine());
index def776d..560b003 100644 (file)
@@ -52,6 +52,10 @@ struct SyntaxErrorObject;
 
 struct ErrorObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(ErrorObject)
+    enum {
+        IsErrorObject = true
+    };
 
     enum ErrorType {
         Error,
index 6e5c137..dc6f310 100644 (file)
@@ -112,7 +112,6 @@ FunctionObject::FunctionObject(InternalClass *ic)
 {
     name = ic->engine->id_undefined;
 
-    type = Type_FunctionObject;
     needsActivation = false;
     strictMode = false;
 }
@@ -130,7 +129,6 @@ void FunctionObject::init(const StringRef n, bool createProto)
     Scope s(internalClass->engine);
     ScopedValue protectThis(s, this);
 
-    type = Type_FunctionObject;
     needsActivation = true;
     strictMode = false;
 #ifndef QT_NO_DEBUG
index 96534cb..0168e13 100644 (file)
@@ -94,6 +94,10 @@ struct Lookup;
 
 struct Q_QML_EXPORT FunctionObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(FunctionObject)
+    enum {
+        IsFunctionObject = true
+    };
     // Used with Managed::subType
     enum FunctionType {
         RegularFunction = 0,
index 6633435..ecdb50b 100644 (file)
@@ -66,6 +66,8 @@ static int indent = 0;
 #endif
 
 
+DEFINE_MANAGED_VTABLE(JsonObject);
+
 class JsonParser
 {
 public:
@@ -884,12 +886,10 @@ QString Stringify::JA(ArrayObjectRef a)
 }
 
 
-JsonObject::JsonObject(ExecutionEngine *engine)
-    : Object(engine)
+JsonObject::JsonObject(InternalClass *ic)
+    : Object(ic)
 {
-    type = Type_JSONObject;
-
-    Scope scope(engine);
+    Scope scope(ic->engine);
     ScopedObject protectThis(scope, this);
 
     defineDefaultProperty(QStringLiteral("parse"), method_parse, 2);
index 3bcbdea..b37b28b 100644 (file)
@@ -51,10 +51,12 @@ QT_BEGIN_NAMESPACE
 namespace QV4 {
 
 struct JsonObject : Object {
+    Q_MANAGED_TYPE(JsonObject)
+    Q_MANAGED
 private:
     typedef QSet<QV4::Object *> V4ObjectSet;
 public:
-    JsonObject(ExecutionEngine *engine);
+    JsonObject(InternalClass *ic);
 
     static ReturnedValue method_parse(CallContext *ctx);
     static ReturnedValue method_stringify(CallContext *ctx);
index fef7489..47f9195 100644 (file)
@@ -47,6 +47,13 @@ using namespace QV4;
 
 const ManagedVTable Managed::static_vtbl =
 {
+    Managed::IsExecutionContext,
+    Managed::IsString,
+    Managed::IsObject,
+    Managed::IsFunctionObject,
+    Managed::IsErrorObject,
+    0,
+    Managed::MyType,
     call,
     construct,
     0 /*markObjects*/,
@@ -101,7 +108,7 @@ ExecutionEngine *Managed::engine() const
 QString Managed::className() const
 {
     const char *s = 0;
-    switch (Type(type)) {
+    switch (Type(internalClass->vtable->type)) {
     case Type_Invalid:
     case Type_String:
         return QString();
@@ -157,18 +164,23 @@ QString Managed::className() const
     case Type_ArgumentsObject:
         s = "Arguments";
         break;
-    case Type_JSONObject:
+    case Type_JsonObject:
         s = "JSON";
         break;
     case Type_MathObject:
         s = "Math";
         break;
+
+    case Type_ExecutionContext:
+        s = "__ExecutionContext";
+        break;
     case Type_ForeachIteratorObject:
         s = "__ForeachIterator";
         break;
     case Type_RegExp:
-        s = "RegExp";
+        s = "__RegExp";
         break;
+
     case Type_QmlSequence:
         s = "QmlSequence";
         break;
index 6397268..afb6bb5 100644 (file)
@@ -69,6 +69,9 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
         template <typename T> \
         QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
 
+#define Q_MANAGED_TYPE(type) \
+    public: \
+        enum { MyType = Type_##type };
 
 struct GCDeletable
 {
@@ -80,6 +83,13 @@ struct GCDeletable
 
 struct ManagedVTable
 {
+    uint isExecutionContext : 1;
+    uint isString : 1;
+    uint isObject : 1;
+    uint isFunctionObject : 1;
+    uint isErrorObject : 1;
+    uint unused : 19;
+    uint type : 8;
     ReturnedValue (*call)(Managed *, CallData *data);
     ReturnedValue (*construct)(Managed *, CallData *data);
     void (*markObjects)(Managed *, ExecutionEngine *e);
@@ -103,6 +113,13 @@ struct ManagedVTable
 #define DEFINE_MANAGED_VTABLE(classname) \
 const QV4::ManagedVTable classname::static_vtbl =    \
 {                                               \
+    classname::IsExecutionContext,   \
+    classname::IsString,   \
+    classname::IsObject,   \
+    classname::IsFunctionObject,   \
+    classname::IsErrorObject,   \
+    0,                                          \
+    classname::MyType,                          \
     call,                                       \
     construct,                                  \
     markObjects,                                \
@@ -123,9 +140,46 @@ const QV4::ManagedVTable classname::static_vtbl =    \
     #classname                                  \
 }
 
+#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
+const QV4::ManagedVTable classname::static_vtbl =    \
+{                                               \
+    classname::IsExecutionContext,   \
+    classname::IsString,   \
+    classname::IsObject,   \
+    classname::IsFunctionObject,   \
+    classname::IsErrorObject,   \
+    0,                                          \
+    classname::MyType,                          \
+    call,                                       \
+    construct,                                  \
+    markObjects,                                \
+    destroy,                                    \
+    0,                                          \
+    get,                                        \
+    getIndexed,                                 \
+    put,                                        \
+    putIndexed,                                 \
+    query,                                      \
+    queryIndexed,                               \
+    deleteProperty,                             \
+    deleteIndexedProperty,                      \
+    getLookup,                                  \
+    setLookup,                                  \
+    isEqualTo,                                  \
+    advanceIterator,                            \
+    #name                                       \
+}
+
 #define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
 const QV4::ManagedVTable classname::static_vtbl =    \
 {                                               \
+    classname::IsExecutionContext,   \
+    classname::IsString,   \
+    classname::IsObject,   \
+    classname::IsFunctionObject,   \
+    classname::IsErrorObject,   \
+    0,                                          \
+    classname::MyType,                          \
     call,                                       \
     construct,                                  \
     markObjects,                                \
@@ -149,6 +203,13 @@ const QV4::ManagedVTable classname::static_vtbl =    \
 struct Q_QML_EXPORT Managed
 {
     Q_MANAGED
+    enum {
+        IsExecutionContext = false,
+        IsString = false,
+        IsObject = false,
+        IsFunctionObject = false,
+        IsErrorObject = false
+    };
 private:
     void *operator new(size_t);
     Managed(const Managed &other);
@@ -183,13 +244,16 @@ public:
         Type_RegExpObject,
         Type_ErrorObject,
         Type_ArgumentsObject,
-        Type_JSONObject,
+        Type_JsonObject,
         Type_MathObject,
+
+        Type_ExecutionContext,
         Type_ForeachIteratorObject,
         Type_RegExp,
 
         Type_QmlSequence
     };
+    Q_MANAGED_TYPE(Invalid)
 
     ExecutionEngine *engine() const;
 
@@ -214,21 +278,21 @@ public:
         return internalClass->vtable == &T::static_vtbl ? static_cast<const T *>(this) : 0;
     }
 
-    String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
-    Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
-    ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
-    FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
-    BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
-    NumberObject *asNumberObject() { return type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
-    StringObject *asStringObject() { return type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
-    DateObject *asDateObject() { return type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
-    ErrorObject *asErrorObject() { return type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
-    ArgumentsObject *asArgumentsObject() { return type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+    String *asString() { return internalClass->vtable->type == Type_String ? reinterpret_cast<String *>(this) : 0; }
+    Object *asObject() { return internalClass->vtable->type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
+    ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+    FunctionObject *asFunctionObject() { return internalClass->vtable->type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+    BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+    NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+    StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+    DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+    ErrorObject *asErrorObject() { return internalClass->vtable->type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+    ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
 
-    bool isListType() const { return type == Type_QmlSequence; }
+    bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
 
-    bool isArrayObject() const { return type == Type_ArrayObject; }
-    bool isStringObject() const { return type == Type_StringObject; }
+    bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
+    bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
 
     QString className() const;
 
@@ -272,10 +336,6 @@ public:
     static void setLookup(Managed *m, Lookup *l, const ValueRef v);
     static bool isEqualTo(Managed *m, Managed *other);
 
-    uint internalType() const {
-        return type;
-    }
-
     ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
 
 
@@ -296,7 +356,7 @@ public:
             uchar strictMode : 1; // used by FunctionObject
             uchar bindingKeyFlag : 1;
             uchar hasAccessorProperty : 1;
-            uchar type;
+            uchar _type;
             mutable uchar subtype;
             uchar flags;
         };
index 5a7af1f..6225d6b 100644 (file)
 
 using namespace QV4;
 
+DEFINE_MANAGED_VTABLE(MathObject);
+
 static const double qt_PI = 2.0 * ::asin(1.0);
 
-MathObject::MathObject(ExecutionEngine *engine)
-    : Object(engine)
+MathObject::MathObject(InternalClass *ic)
+    : Object(ic)
 {
-    type = Type_MathObject;
-
-    Scope scope(engine);
+    Scope scope(ic->engine);
     ScopedObject protectThis(scope, this);
 
     defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
index 6fe3db3..45f8e7c 100644 (file)
@@ -49,7 +49,9 @@ namespace QV4 {
 
 struct MathObject: Object
 {
-    MathObject(ExecutionEngine *engine);
+    Q_MANAGED
+    Q_MANAGED_TYPE(MathObject)
+    MathObject(InternalClass *ic);
 
     static ReturnedValue method_abs(CallContext *context);
     static ReturnedValue method_acos(CallContext *context);
index 1154736..559792d 100644 (file)
@@ -73,7 +73,6 @@ Object::Object(ExecutionEngine *engine)
     : Managed(engine->objectClass)
     , memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
 {
-    type = Type_Object;
     flags = SimpleArray;
 }
 
@@ -82,7 +81,6 @@ Object::Object(InternalClass *ic)
     , memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
 {
     Q_ASSERT(internalClass->vtable && internalClass->vtable != &Managed::static_vtbl);
-    type = Type_Object;
     flags = SimpleArray;
 
     if (internalClass->size >= memberDataAlloc) {
@@ -1438,7 +1436,6 @@ void ArrayObject::init(ExecutionEngine *engine)
 {
     Q_UNUSED(engine);
 
-    type = Type_ArrayObject;
     memberData[LengthPropertyIndex].value = Primitive::fromInt32(0);
 }
 
index 23f2f68..5c03b1f 100644 (file)
@@ -102,6 +102,10 @@ struct URIErrorPrototype;
 
 struct Q_QML_EXPORT Object: Managed {
     Q_MANAGED
+    Q_MANAGED_TYPE(Object)
+    enum {
+        IsObject = true
+    };
     uint memberDataAlloc;
     Property *memberData;
 
@@ -328,40 +332,39 @@ private:
 
 struct BooleanObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(BooleanObject)
     SafeValue value;
     BooleanObject(ExecutionEngine *engine, const ValueRef val)
         : Object(engine->booleanClass) {
-        type = Type_BooleanObject;
         value = val;
     }
 protected:
     BooleanObject(InternalClass *ic)
         : Object(ic) {
-        setVTable(&static_vtbl);
-        type = Type_BooleanObject;
+        Q_ASSERT(internalClass->vtable == &static_vtbl);
         value = Encode(false);
     }
 };
 
 struct NumberObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(NumberObject)
     SafeValue value;
     NumberObject(ExecutionEngine *engine, const ValueRef val)
         : Object(engine->numberClass) {
-        type = Type_NumberObject;
         value = val;
     }
 protected:
     NumberObject(InternalClass *ic)
         : Object(ic) {
-        setVTable(&static_vtbl);
-        type = Type_NumberObject;
+        Q_ASSERT(internalClass->vtable == &static_vtbl);
         value = Encode((int)0);
     }
 };
 
 struct ArrayObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(ArrayObject)
     enum {
         LengthPropertyIndex = 0
     };
index 6c333b3..33228ce 100644 (file)
@@ -86,11 +86,11 @@ struct Q_QML_EXPORT ObjectIterator
 
 struct ForEachIteratorObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(ForeachIteratorObject)
     ObjectIterator it;
     ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
         : Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
         setVTable(&static_vtbl);
-        type = Type_ForeachIteratorObject;
     }
 
     ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
index 7ca790b..a8e78b4 100644 (file)
@@ -105,9 +105,9 @@ ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
 void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
 {
     Scope scope(v4);
-    ScopedObject o(scope);
+    ScopedObject o(scope, this);
 
-    ctor->defineReadonlyProperty(v4->id_prototype, (o = this));
+    ctor->defineReadonlyProperty(v4->id_prototype, o);
     ctor->defineReadonlyProperty(v4->id_length, Primitive::fromInt32(1));
     ctor->defineDefaultProperty(QStringLiteral("getPrototypeOf"), method_getPrototypeOf, 1);
     ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
index 41ff9f9..8544970 100644 (file)
@@ -99,8 +99,6 @@ RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase,
     , m_ignoreCase(ignoreCase)
     , m_multiLine(multiline)
 {
-    type = Type_RegExpObject;
-
     if (!engine)
         return;
     const char* error = 0;
index 9041ff2..d8e9930 100644 (file)
@@ -94,6 +94,7 @@ public:
 class RegExp : public Managed
 {
     Q_MANAGED
+    Q_MANAGED_TYPE(RegExp)
 public:
     static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
     ~RegExp();
index 468fb34..425fb8a 100644 (file)
@@ -76,6 +76,7 @@ RegExpObject::RegExpObject(InternalClass *ic)
     , value(RegExp::create(ic->engine, QString(), false, false))
     , global(false)
 {
+    Q_ASSERT(internalClass->vtable == &static_vtbl);
     init(ic->engine);
 }
 
@@ -143,7 +144,6 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re)
 void RegExpObject::init(ExecutionEngine *engine)
 {
     setVTable(&static_vtbl);
-    type = Type_RegExpObject;
 
     Scope scope(engine);
     ScopedObject protectThis(scope, this);
index 0129f8d..bd91e8f 100644 (file)
@@ -67,6 +67,7 @@ class RegExp;
 
 struct RegExpObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(RegExpObject)
     // needs to be compatible with the flags in qv4jsir_p.h
     enum Flags {
         RegExp_Global     = 0x01,
index 8b0e31c..988762c 100644 (file)
@@ -166,6 +166,7 @@ template <typename Container>
 class QQmlSequence : public QV4::Object
 {
     Q_MANAGED
+    Q_MANAGED_TYPE(QmlSequence)
 public:
     QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
         : QV4::Object(InternalClass::create(engine, &static_vtbl, engine->sequencePrototype.asObject()))
@@ -174,7 +175,6 @@ public:
         , m_propertyIndex(-1)
         , m_isReference(false)
     {
-        type = Type_QmlSequence;
         flags &= ~SimpleArray;
         QV4::Scope scope(engine);
         QV4::ScopedObject protectThis(scope, this);
@@ -188,7 +188,6 @@ public:
         , m_propertyIndex(propertyIndex)
         , m_isReference(true)
     {
-        type = Type_QmlSequence;
         flags &= ~SimpleArray;
         QV4::Scope scope(engine);
         QV4::ScopedObject protectThis(scope, this);
index e5633eb..0b38b5c 100644 (file)
@@ -103,6 +103,13 @@ static uint toArrayIndex(const char *ch, const char *end, bool *ok)
 
 const ManagedVTable String::static_vtbl =
 {
+    String::IsExecutionContext,
+    String::IsString,
+    String::IsObject,
+    String::IsFunctionObject,
+    String::IsErrorObject,
+    0,
+    String::MyType,
     call,
     construct,
     markObjects,
@@ -233,10 +240,10 @@ bool String::isEqualTo(Managed *t, Managed *o)
     if (t == o)
         return true;
 
-    if (o->type != Type_String)
+    if (o->internalClass->vtable->type != Type_String)
         return false;
 
-    Q_ASSERT(t->type == Type_String);
+    Q_ASSERT(t->internalClass->vtable->type == Type_String);
     String *that = static_cast<String *>(t);
     String *other = static_cast<String *>(o);
     if (that->hashValue() != other->hashValue())
@@ -257,7 +264,6 @@ String::String(ExecutionEngine *engine, const QString &text)
 {
     _text->ref.ref();
     len = _text->size;
-    type = Type_String;
     subtype = StringType_Unknown;
 }
 
@@ -267,7 +273,6 @@ String::String(ExecutionEngine *engine, String *l, String *r)
     , stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength))
     , len(l->len + r->len)
 {
-    type = Type_String;
     subtype = StringType_Unknown;
 
     if (!l->largestSubLength && l->len > largestSubLength)
index 64e15b0..7e2824d 100644 (file)
@@ -53,6 +53,11 @@ struct Identifier;
 
 struct Q_QML_EXPORT String : public Managed {
     Q_MANAGED
+    Q_MANAGED_TYPE(String)
+    enum {
+        IsString = true
+    };
+
     enum StringType {
         StringType_Unknown,
         StringType_Regular,
@@ -63,7 +68,7 @@ struct Q_QML_EXPORT String : public Managed {
     String()
         : Managed(0), _text(QStringData::sharedNull()), identifier(0)
         , stringHash(UINT_MAX), largestSubLength(0), len(0)
-    { type = Type_String; subtype = StringType_Unknown; }
+    { subtype = StringType_Unknown; }
     String(ExecutionEngine *engine, const QString &text);
     String(ExecutionEngine *engine, String *l, String *n);
     ~String() {
index d468fb6..39667f0 100644 (file)
@@ -80,8 +80,7 @@ DEFINE_MANAGED_VTABLE(StringObject);
 StringObject::StringObject(InternalClass *ic)
     : Object(ic)
 {
-    setVTable(&static_vtbl);
-    type = Type_StringObject;
+    Q_ASSERT(internalClass->vtable == &static_vtbl);
 
     Scope scope(engine());
     ScopedObject protectThis(scope, this);
@@ -97,7 +96,6 @@ StringObject::StringObject(ExecutionEngine *engine, const ValueRef val)
     : Object(engine->stringObjectClass)
 {
     setVTable(&static_vtbl);
-    type = Type_StringObject;
 
     Scope scope(engine);
     ScopedObject protectThis(scope, this);
index e8e46b8..b91cc48 100644 (file)
@@ -51,6 +51,7 @@ namespace QV4 {
 
 struct StringObject: Object {
     Q_MANAGED
+    Q_MANAGED_TYPE(StringObject)
 
     SafeValue value;
     mutable Property tmpProperty;
index 680c746..b93fcbe 100644 (file)
@@ -64,13 +64,13 @@ inline bool Value::isString() const
 {
     if (!isManaged())
         return false;
-    return managed() && managed()->type == Managed::Type_String;
+    return managed() && managed()->internalClass->vtable->isString;
 }
 inline bool Value::isObject() const
 {
     if (!isManaged())
         return false;
-    return managed() && managed()->type != Managed::Type_String;
+    return managed() && managed()->internalClass->vtable->isObject;
 }
 
 inline bool Value::isPrimitive() const
index 36e0da5..c814298 100644 (file)
@@ -62,7 +62,6 @@ public:
         : QV4::Object(engine)
     {
         setVTable(&static_vtbl);
-        type = Type_Object;
     }
 
     QLocale locale;