diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-06-25 14:58:51 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-07-03 08:08:31 +0000 |
commit | 2aabdd187aae8a953cfcebac8f6c1ba7b19a0727 (patch) | |
tree | 832ef17f2f6433240ec4d329421d119276152792 /src | |
parent | 12d8b8c9e4ff05707df7bda479e69d997799c486 (diff) |
Unify the managed and object vtables
Allow for nullptr entries in the vtable. To nevertheless
get some decent error checking if one of the methods is
reimplemented, use a base class for Managed that contains
a full set of the vtable entries all being nullptr's.
Change-Id: Ibc53973b539f87331e8e465a6c44436a30acbefd
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 23 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 19 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed.cpp | 21 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vtable_p.h | 189 |
12 files changed, 149 insertions, 158 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 74ff1e2fc3..ce1d0503df 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -47,26 +47,7 @@ using namespace QV4; -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON - -const QV4::VTable QV4::ArrayData::static_vtbl = { - nullptr, - 0, - 0, - QV4::ArrayData::IsExecutionContext, - QV4::ArrayData::IsString, - QV4::ArrayData::IsObject, - QV4::ArrayData::IsFunctionObject, - QV4::ArrayData::IsErrorObject, - QV4::ArrayData::IsArrayData, - QV4::ArrayData::IsStringOrSymbol, - QV4::ArrayData::MyType, - { 0, 0, 0, 0 }, - "ArrayData", - Q_VTABLE_FUNCTION(QV4::ArrayData, destroy), - ArrayData::Data::markObjects, - isEqualTo -}; +DEFINE_MANAGED_VTABLE(ArrayData); const ArrayVTable SimpleArrayData::static_vtbl = { @@ -100,8 +81,6 @@ const ArrayVTable SparseArrayData::static_vtbl = SparseArrayData::length }; -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF - Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SimpleArrayData)); Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SparseArrayData)); diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index ac5b430356..35a9488f1f 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -215,6 +215,17 @@ struct Q_QML_EXPORT ArrayData : public Managed static void sort(ExecutionEngine *engine, Object *thisObject, const Value &comparefn, uint dataLen); static uint append(Object *obj, ArrayObject *otherObj, uint n); static void insert(Object *o, uint index, const Value *v, bool isAccessor = false); + +protected: + // Vtable methods required to get things to compile + static ReturnedValue get(const Managed *, PropertyKey, const Value *, bool *) { + Q_UNREACHABLE(); + return Encode::undefined(); + } + static bool put(Managed *, PropertyKey, const Value &, Value *) { + Q_UNREACHABLE(); + return false; + } }; struct Q_QML_EXPORT SimpleArrayData : public ArrayData @@ -239,6 +250,10 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData static ReturnedValue pop_front(Object *o); static uint truncate(Object *o, uint newLen); static uint length(const Heap::ArrayData *d); + +protected: + using ArrayData::get; + using ArrayData::put; }; struct Q_QML_EXPORT SparseArrayData : public ArrayData @@ -265,6 +280,10 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData static ReturnedValue pop_front(Object *o); static uint truncate(Object *o, uint newLen); static uint length(const Heap::ArrayData *d); + +protected: + using ArrayData::get; + using ArrayData::put; }; namespace Heap { diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 26e64728dc..fb1f647ced 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -203,6 +203,12 @@ struct Q_QML_EXPORT ExecutionContext : public Managed inline CallContext *asCallContext(); inline const CallContext *asCallContext() const; + +protected: + // vtable method required for compilation + static bool deleteProperty(Managed *, PropertyKey) { + Q_UNREACHABLE(); + } }; struct Q_QML_EXPORT CallContext : public ExecutionContext diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index b7b6f83735..69be9a8c84 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -85,8 +85,8 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, bool createProto) { - jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call; - jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor; + jsCall = vtable()->call; + jsConstruct = vtable()->callAsConstructor; Object::init(); this->scope.set(scope->engine(), scope->d()); @@ -103,8 +103,8 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function, bool createProto) { - jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call; - jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor; + jsCall = vtable()->call; + jsConstruct = vtable()->callAsConstructor; Object::init(); setFunction(function); @@ -128,8 +128,8 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, const QString &nam void Heap::FunctionObject::init() { - jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call; - jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor; + jsCall = vtable()->call; + jsConstruct = vtable()->callAsConstructor; Object::init(); this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d()); @@ -193,7 +193,7 @@ Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *sco return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function); } -Heap::FunctionObject *FunctionObject::createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, jsCallFunction code, int argumentCount) +Heap::FunctionObject *FunctionObject::createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount) { Scope scope(engine); ScopedString name(scope, nameOrSymbol); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index b87eab2fcf..02b75216d8 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -70,8 +70,8 @@ namespace Heap { #define FunctionObjectMembers(class, Member) \ Member(class, Pointer, ExecutionContext *, scope) \ Member(class, NoMark, Function *, function) \ - Member(class, NoMark, jsCallFunction, jsCall) \ - Member(class, NoMark, jsConstructFunction, jsConstruct) + Member(class, NoMark, VTable::Call, jsCall) \ + Member(class, NoMark, VTable::CallAsConstructor, jsConstruct) DECLARE_HEAP_OBJECT(FunctionObject, Object) { DECLARE_MARKOBJECTS(FunctionObject); @@ -182,7 +182,7 @@ struct Q_QML_EXPORT FunctionObject: Object { static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function); static Heap::FunctionObject *createConstructorFunction(ExecutionContext *scope, Function *function); static Heap::FunctionObject *createMemberFunction(ExecutionContext *scope, Function *function); - static Heap::FunctionObject *createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, jsCallFunction code, int argumentCount); + static Heap::FunctionObject *createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount); bool strictMode() const { return d()->function ? d()->function->isStrict() : false; } bool isBinding() const; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 9321b9dd64..05d37c85f5 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -43,26 +43,7 @@ using namespace QV4; - -const VTable Managed::static_vtbl = -{ - nullptr, - 0, - 0, - Managed::IsExecutionContext, - Managed::IsString, - Managed::IsObject, - Managed::IsFunctionObject, - Managed::IsErrorObject, - Managed::IsArrayData, - Managed::IsStringOrSymbol, - Managed::MyType, - { 0, 0, 0, 0 }, - "Managed", - nullptr, - nullptr /*markObjects*/, - isEqualTo -}; +DEFINE_MANAGED_VTABLE(Managed); DEFINE_MANAGED_VTABLE(InternalClass); diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 34cf73340d..da365f706f 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -106,7 +106,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {} static Heap::InternalClass *defaultInternalClass(QV4::EngineBase *e) \ { return e->internalClasses(QV4::EngineBase::Class_##c); } -struct Q_QML_PRIVATE_EXPORT Managed : Value +struct Q_QML_PRIVATE_EXPORT Managed : Value, VTableBase { V4_MANAGED_ITSELF(Base, Managed) enum { @@ -181,8 +181,6 @@ public: bool markBit() const { return d()->isMarked(); } inline void mark(MarkStack *markStack); - static void destroy(Heap::Base *) {} - Q_ALWAYS_INLINE Heap::Base *heapObject() const { return m(); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index a59d278f7d..5481b36aa2 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -144,7 +144,7 @@ void Object::defineDefaultProperty(const QString &name, const Value &value, Prop defineDefaultProperty(s, value, attributes); } -void Object::defineDefaultProperty(const QString &name, jsCallFunction code, +void Object::defineDefaultProperty(const QString &name, VTable::Call code, int argumentCount, PropertyAttributes attributes) { ExecutionEngine *e = engine(); @@ -154,7 +154,7 @@ void Object::defineDefaultProperty(const QString &name, jsCallFunction code, defineDefaultProperty(s, function, attributes); } -void Object::defineDefaultProperty(StringOrSymbol *nameOrSymbol, jsCallFunction code, +void Object::defineDefaultProperty(StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount, PropertyAttributes attributes) { ExecutionEngine *e = engine(); @@ -163,7 +163,7 @@ void Object::defineDefaultProperty(StringOrSymbol *nameOrSymbol, jsCallFunction defineDefaultProperty(nameOrSymbol, function, attributes); } -void Object::defineAccessorProperty(const QString &name, jsCallFunction getter, jsCallFunction setter) +void Object::defineAccessorProperty(const QString &name, VTable::Call getter, VTable::Call setter) { ExecutionEngine *e = engine(); Scope scope(e); @@ -171,7 +171,7 @@ void Object::defineAccessorProperty(const QString &name, jsCallFunction getter, defineAccessorProperty(s, getter, setter); } -void Object::defineAccessorProperty(StringOrSymbol *name, jsCallFunction getter, jsCallFunction setter) +void Object::defineAccessorProperty(StringOrSymbol *name, VTable::Call getter, VTable::Call setter) { ExecutionEngine *v4 = engine(); QV4::Scope scope(v4); @@ -892,8 +892,7 @@ bool Object::setPrototypeOf(Managed *m, const Object *proto) while (p) { if (p == o->d()) return false; - if (reinterpret_cast<const ObjectVTable *>(p->vtable())->getPrototypeOf != - reinterpret_cast<const ObjectVTable *>(Object::staticVTable())->getPrototypeOf) + if (p->vtable()->getPrototypeOf != Object::staticVTable()->getPrototypeOf) break; p = p->prototype(); } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 272f1dbb9d..56f3c3f881 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -166,7 +166,7 @@ struct Q_QML_EXPORT Object: Managed { void setProperty(ExecutionEngine *engine, uint index, Value v) const { d()->setProperty(engine, index, v); } void setProperty(ExecutionEngine *engine, uint index, Heap::Base *b) const { d()->setProperty(engine, index, b); } - const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable()); } + const VTable *vtable() const { return d()->vtable(); } PropertyAttributes getOwnProperty(PropertyKey id, Property *p = nullptr) { return vtable()->getOwnProperty(this, id, p); @@ -199,12 +199,12 @@ struct Q_QML_EXPORT Object: Managed { insertMember(name, value, attributes); } void defineDefaultProperty(const QString &name, const Value &value, PropertyAttributes attributes = Attr_Data|Attr_NotEnumerable); - void defineDefaultProperty(const QString &name, jsCallFunction code, + void defineDefaultProperty(const QString &name, VTable::Call code, int argumentCount = 0, PropertyAttributes attributes = Attr_Data|Attr_NotEnumerable); - void defineDefaultProperty(StringOrSymbol *name, jsCallFunction code, + void defineDefaultProperty(StringOrSymbol *name, VTable::Call code, int argumentCount = 0, PropertyAttributes attributes = Attr_Data|Attr_NotEnumerable); - void defineAccessorProperty(const QString &name, jsCallFunction getter, jsCallFunction setter); - void defineAccessorProperty(StringOrSymbol *name, jsCallFunction getter, jsCallFunction setter); + void defineAccessorProperty(const QString &name, VTable::Call getter, VTable::Call setter); + void defineAccessorProperty(StringOrSymbol *name, VTable::Call getter, VTable::Call setter); /* Fixed: Writable: false, Enumerable: false, Configurable: false */ void defineReadonlyProperty(const QString &name, const Value &value); void defineReadonlyProperty(String *name, const Value &value); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index cd8b1b6da1..2fcdd02bd2 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -257,7 +257,7 @@ PropertyKey StringOrSymbol::toPropertyKey() const { return propertyKey(); } -uint String::getLength(const Managed *m) +qint64 String::getLength(const Managed *m) { return static_cast<const String *>(m)->d()->length(); } diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 65efbe31c2..23319eefb1 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -238,7 +238,7 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol { protected: static bool isEqualTo(Managed *that, Managed *o); - static uint getLength(const Managed *m); + static qint64 getLength(const Managed *m); #endif public: diff --git a/src/qml/jsruntime/qv4vtable_p.h b/src/qml/jsruntime/qv4vtable_p.h index df33dc773c..2acc868d3e 100644 --- a/src/qml/jsruntime/qv4vtable_p.h +++ b/src/qml/jsruntime/qv4vtable_p.h @@ -59,6 +59,25 @@ namespace QV4 { struct VTable { typedef void (*Destroy)(Heap::Base *); + typedef void (*MarkObjects)(Heap::Base *, MarkStack *markStack); + typedef bool (*IsEqualTo)(Managed *m, Managed *other); + + typedef ReturnedValue (*Get)(const Managed *, PropertyKey id, const Value *receiver, bool *hasProperty); + typedef bool (*Put)(Managed *, PropertyKey id, const Value &value, Value *receiver); + typedef bool (*DeleteProperty)(Managed *m, PropertyKey id); + typedef bool (*HasProperty)(const Managed *m, PropertyKey id); + typedef PropertyAttributes (*GetOwnProperty)(Managed *m, PropertyKey id, Property *p); + typedef bool (*DefineOwnProperty)(Managed *m, PropertyKey id, const Property *p, PropertyAttributes attrs); + typedef bool (*IsExtensible)(const Managed *); + typedef bool (*PreventExtensions)(Managed *); + typedef Heap::Object *(*GetPrototypeOf)(const Managed *); + typedef bool (*SetPrototypeOf)(Managed *, const Object *); + typedef qint64 (*GetLength)(const Managed *m); + typedef void (*AdvanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); + typedef ReturnedValue (*InstanceOf)(const Object *typeObject, const Value &var); + + typedef ReturnedValue (*Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); + typedef ReturnedValue (*CallAsConstructor)(const FunctionObject *, const Value *argv, int argc); const VTable * const parent; quint32 inlinePropertyOffset : 16; @@ -73,33 +92,52 @@ struct VTable quint8 type; quint8 unused[4]; const char *className; + Destroy destroy; - void (*markObjects)(Heap::Base *, MarkStack *markStack); - bool (*isEqualTo)(Managed *m, Managed *other); + MarkObjects markObjects; + IsEqualTo isEqualTo; + + Get get; + Put put; + DeleteProperty deleteProperty; + HasProperty hasProperty; + GetOwnProperty getOwnProperty; + DefineOwnProperty defineOwnProperty; + IsExtensible isExtensible; + PreventExtensions preventExtensions; + GetPrototypeOf getPrototypeOf; + SetPrototypeOf setPrototypeOf; + GetLength getLength; + AdvanceIterator advanceIterator; + InstanceOf instanceOf; + + Call call; + CallAsConstructor callAsConstructor; }; -#define Q_VTABLE_FUNCTION(classname, func) \ - (classname::func == QV4::Managed::func ? 0 : classname::func) - -// Q_VTABLE_FUNCTION triggers a bogus tautological-compare warning in GCC6+ -#if (defined(Q_CC_GNU) && Q_CC_GNU >= 600) -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ - QT_WARNING_PUSH; \ - QT_WARNING_DISABLE_GCC("-Wtautological-compare") - -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \ - ;QT_WARNING_POP -#elif defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ - QT_WARNING_PUSH; \ - QT_WARNING_DISABLE_CLANG("-Wtautological-compare") - -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \ - ;QT_WARNING_POP -#else -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON -#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF -#endif + +struct VTableBase { +protected: + static constexpr VTable::Destroy destroy = nullptr; + static constexpr VTable::IsEqualTo isEqualTo = nullptr; + + static constexpr VTable::Get get = nullptr; + static constexpr VTable::Put put = nullptr; + static constexpr VTable::DeleteProperty deleteProperty = nullptr; + static constexpr VTable::HasProperty hasProperty = nullptr; + static constexpr VTable::GetOwnProperty getOwnProperty = nullptr; + static constexpr VTable::DefineOwnProperty defineOwnProperty = nullptr; + static constexpr VTable::IsExtensible isExtensible = nullptr; + static constexpr VTable::PreventExtensions preventExtensions = nullptr; + static constexpr VTable::GetPrototypeOf getPrototypeOf = nullptr; + static constexpr VTable::SetPrototypeOf setPrototypeOf = nullptr; + static constexpr VTable::GetLength getLength = nullptr; + static constexpr VTable::AdvanceIterator advanceIterator = nullptr; + static constexpr VTable::InstanceOf instanceOf = nullptr; + + static constexpr VTable::Call call = nullptr; + static constexpr VTable::CallAsConstructor callAsConstructor = nullptr; +}; #define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \ { \ @@ -107,25 +145,41 @@ struct VTable (sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \ (sizeof(classname::Data) + (classname::NInlineProperties*sizeof(QV4::Value)) + QV4::Chunk::SlotSize - 1)/QV4::Chunk::SlotSize*QV4::Chunk::SlotSize/sizeof(QV4::Value) \ - (sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \ - classname::IsExecutionContext, \ - classname::IsString, \ - classname::IsObject, \ - classname::IsFunctionObject, \ - classname::IsErrorObject, \ - classname::IsArrayData, \ - classname::IsStringOrSymbol, \ - classname::MyType, \ - { 0, 0, 0, 0 }, \ + classname::IsExecutionContext, \ + classname::IsString, \ + classname::IsObject, \ + classname::IsFunctionObject, \ + classname::IsErrorObject, \ + classname::IsArrayData, \ + classname::IsStringOrSymbol, \ + classname::MyType, \ + { 0, 0, 0, 0 }, \ #classname, \ - Q_VTABLE_FUNCTION(classname, destroy), \ - classname::Data::markObjects, \ - isEqualTo \ -} \ + \ + classname::destroy, \ + classname::Data::markObjects, \ + classname::isEqualTo, \ + \ + classname::get, \ + classname::put, \ + classname::deleteProperty, \ + classname::hasProperty, \ + classname::getOwnProperty, \ + classname::defineOwnProperty, \ + classname::isExtensible, \ + classname::preventExtensions, \ + classname::getPrototypeOf, \ + classname::setPrototypeOf, \ + classname::getLength, \ + classname::advanceIterator, \ + classname::instanceOf, \ + \ + classname::call, \ + classname::callAsConstructor, \ +} #define DEFINE_MANAGED_VTABLE(classname) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ -const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF +const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0) #define V4_OBJECT2(DataClass, superClass) \ private: \ @@ -135,8 +189,8 @@ QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF Q_MANAGED_CHECK \ typedef QV4::Heap::DataClass Data; \ typedef superClass SuperClass; \ - static const QV4::ObjectVTable static_vtbl; \ - static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ + static const QV4::VTable static_vtbl; \ + static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \ V4_MANAGED_SIZE_TEST \ QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \ QV4::Heap::DataClass *d() const { \ @@ -150,60 +204,15 @@ QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF static QV4::Object *defaultPrototype(QV4::ExecutionEngine *e) \ { return e->p(); } -typedef ReturnedValue (*jsCallFunction)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); -typedef ReturnedValue (*jsConstructFunction)(const FunctionObject *, const Value *argv, int argc); - -struct ObjectVTable -{ - VTable vTable; - jsCallFunction call; - jsConstructFunction callAsConstructor; - ReturnedValue (*get)(const Managed *, PropertyKey id, const Value *receiver, bool *hasProperty); - bool (*put)(Managed *, PropertyKey id, const Value &value, Value *receiver); - bool (*deleteProperty)(Managed *m, PropertyKey id); - bool (*hasProperty)(const Managed *m, PropertyKey id); - PropertyAttributes (*getOwnProperty)(Managed *m, PropertyKey id, Property *p); - bool (*defineOwnProperty)(Managed *m, PropertyKey id, const Property *p, PropertyAttributes attrs); - bool (*isExtensible)(const Managed *); - bool (*preventExtensions)(Managed *); - Heap::Object *(*getPrototypeOf)(const Managed *); - bool (*setPrototypeOf)(Managed *, const Object *); - qint64 (*getLength)(const Managed *m); - void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - ReturnedValue (*instanceOf)(const Object *typeObject, const Value &var); -}; #define DEFINE_OBJECT_VTABLE_BASE(classname) \ -const QV4::ObjectVTable classname::static_vtbl = \ -{ \ - DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl.vTable), \ - call, \ - callAsConstructor, \ - get, \ - put, \ - deleteProperty, \ - hasProperty, \ - getOwnProperty, \ - defineOwnProperty, \ - isExtensible, \ - preventExtensions, \ - getPrototypeOf, \ - setPrototypeOf, \ - getLength, \ - advanceIterator, \ - instanceOf \ -} + const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl) #define DEFINE_OBJECT_VTABLE(classname) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ -DEFINE_OBJECT_VTABLE_BASE(classname) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF +DEFINE_OBJECT_VTABLE_BASE(classname) #define DEFINE_OBJECT_TEMPLATE_VTABLE(classname) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \ -template<> DEFINE_OBJECT_VTABLE_BASE(classname) \ -QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF - +template<> DEFINE_OBJECT_VTABLE_BASE(classname) } |