From da5ac2aabd504e96156efede8aebc6b78370fb7d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 14 Feb 2013 15:00:06 +0100 Subject: [PATCH] Move the destructor into the new vtable. This makes all runtime structures fully non virtual. Change-Id: I804568ca9bc33d4be0324ed542df8eab5892c0eb Reviewed-by: Simon Hausmann --- src/v4/qv4argumentsobject.cpp | 5 +++++ src/v4/qv4argumentsobject.h | 5 ++++- src/v4/qv4errorobject.cpp | 3 +++ src/v4/qv4errorobject.h | 3 +++ src/v4/qv4functionobject.cpp | 9 +++++---- src/v4/qv4functionobject.h | 3 ++- src/v4/qv4managed.cpp | 13 ++++--------- src/v4/qv4managed.h | 22 ++++++++++------------ src/v4/qv4mm.cpp | 2 +- src/v4/qv4object.cpp | 6 ++++++ src/v4/qv4object.h | 1 + src/v4/qv4regexpobject.cpp | 6 ++++++ src/v4/qv4regexpobject.h | 5 +++++ src/v4/qv4string.cpp | 15 +++++++++++++++ src/v4/qv4string.h | 7 ++++++- 15 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/v4/qv4argumentsobject.cpp b/src/v4/qv4argumentsobject.cpp index d1791e0..f2afe19 100644 --- a/src/v4/qv4argumentsobject.cpp +++ b/src/v4/qv4argumentsobject.cpp @@ -89,6 +89,11 @@ ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterC } } +void ArgumentsObject::destroy(Managed *that) +{ + static_cast(that)->~ArgumentsObject(); +} + bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc) { PropertyDescriptor *pd = arrayAt(index); diff --git a/src/v4/qv4argumentsobject.h b/src/v4/qv4argumentsobject.h index acbcc75..13f6b40 100644 --- a/src/v4/qv4argumentsobject.h +++ b/src/v4/qv4argumentsobject.h @@ -80,11 +80,14 @@ struct ArgumentsObject: Object { ExecutionContext *context; QVector mappedArguments; ArgumentsObject(ExecutionContext *context, int formalParameterCount, int actualParameterCount); + ~ArgumentsObject() {} bool defineOwnProperty(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc); - static const ManagedVTable static_vtbl; static void markObjects(Managed *that); +protected: + static const ManagedVTable static_vtbl; + static void destroy(Managed *); }; } diff --git a/src/v4/qv4errorobject.cpp b/src/v4/qv4errorobject.cpp index 418dbb7..addf163 100644 --- a/src/v4/qv4errorobject.cpp +++ b/src/v4/qv4errorobject.cpp @@ -88,10 +88,13 @@ void ErrorObject::setNameProperty(ExecutionContext *ctx) defineDefaultProperty(ctx, QLatin1String("name"), Value::fromString(ctx, className())); } +DEFINE_MANAGED_VTABLE(SyntaxErrorObject); + SyntaxErrorObject::SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message) : ErrorObject(ctx->engine, message ? Value::fromString(message->buildFullMessage(ctx)) : ctx->argument(0)) , msg(message) { + vtbl = &static_vtbl; subtype = SyntaxError; prototype = ctx->engine->syntaxErrorPrototype; setNameProperty(ctx); diff --git a/src/v4/qv4errorobject.h b/src/v4/qv4errorobject.h index ae132a9..c03d822 100644 --- a/src/v4/qv4errorobject.h +++ b/src/v4/qv4errorobject.h @@ -87,11 +87,14 @@ struct ReferenceErrorObject: ErrorObject { struct SyntaxErrorObject: ErrorObject { SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *msg); ~SyntaxErrorObject() { delete msg; } + static void destroy(Managed *that) { static_cast(that)->~SyntaxErrorObject(); } DiagnosticMessage *message() { return msg; } private: DiagnosticMessage *msg; +protected: + static const ManagedVTable static_vtbl; }; struct TypeErrorObject: ErrorObject { diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index caa6987..af23182 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -355,10 +355,6 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function) } } -ScriptFunction::~ScriptFunction() -{ -} - Value ScriptFunction::construct(Managed *that, ExecutionContext *context, Value *args, int argc) { ScriptFunction *f = static_cast(that); @@ -510,6 +506,11 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va *insertMember(scope->engine->id_caller) = pd; } +void BoundFunction::destroy(Managed *that) +{ + static_cast(that)->~BoundFunction(); +} + Value BoundFunction::call(Managed *that, ExecutionContext *context, const Value &, Value *args, int argc) { BoundFunction *f = static_cast(that); diff --git a/src/v4/qv4functionobject.h b/src/v4/qv4functionobject.h index cf99b78..ebf14f8 100644 --- a/src/v4/qv4functionobject.h +++ b/src/v4/qv4functionobject.h @@ -219,7 +219,6 @@ protected: struct ScriptFunction: FunctionObject { ScriptFunction(ExecutionContext *scope, VM::Function *function); - ~ScriptFunction(); static Value construct(Managed *, ExecutionContext *context, Value *args, int argc); static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int); @@ -236,10 +235,12 @@ struct BoundFunction: FunctionObject { BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector &boundArgs); ~BoundFunction() {} + static Value construct(Managed *, ExecutionContext *context, Value *args, int argc); static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int); static const ManagedVTable static_vtbl; + static void destroy(Managed *); static void markObjects(Managed *that); static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value); }; diff --git a/src/v4/qv4managed.cpp b/src/v4/qv4managed.cpp index ea4004e..f458565 100644 --- a/src/v4/qv4managed.cpp +++ b/src/v4/qv4managed.cpp @@ -47,20 +47,15 @@ using namespace QQmlJS::VM; const ManagedVTable Managed::static_vtbl = { - "Managed", + call, + construct, 0 /*markObjects*/, + destroy, hasInstance, - construct, - call, - ManagedVTable::EndOfVTable + "Managed", }; -Managed::~Managed() -{ - _data = 0; -} - void *Managed::operator new(size_t size, MemoryManager *mm) { assert(mm); diff --git a/src/v4/qv4managed.h b/src/v4/qv4managed.h index 54c8cf4..94aaaf3 100644 --- a/src/v4/qv4managed.h +++ b/src/v4/qv4managed.h @@ -76,26 +76,23 @@ struct Value; struct ManagedVTable { - enum _EndOfVTable { - EndOfVTable - }; - const char *className; + Value (*call)(Managed *, ExecutionContext *context, const Value &thisObject, Value *args, int argc); + Value (*construct)(Managed *, ExecutionContext *context, Value *args, int argc); void (*markObjects)(Managed *); + void (*destroy)(Managed *); bool (*hasInstance)(Managed *, ExecutionContext *ctx, const Value &value); - Value (*construct)(Managed *, ExecutionContext *context, Value *args, int argc); - Value (*call)(Managed *, ExecutionContext *context, const Value &thisObject, Value *args, int argc); - _EndOfVTable endofVTable; + const char *className; }; #define DEFINE_MANAGED_VTABLE(classname) \ const ManagedVTable classname::static_vtbl = \ { \ - #classname, \ + call, \ + construct, \ markObjects, \ + destroy, \ hasInstance, \ - construct, \ - call, \ - ManagedVTable::EndOfVTable \ + #classname \ } @@ -110,7 +107,6 @@ protected: Managed() : vtbl(&static_vtbl), _data(0) { inUse = 1; extensible = 1; } - virtual ~Managed(); public: void *operator new(size_t size, MemoryManager *mm); @@ -177,6 +173,7 @@ public: inline Value construct(ExecutionContext *context, Value *args, int argc); inline Value call(ExecutionContext *context, const Value &thisObject, Value *args, int argc); + static void destroy(Managed *that) { that->_data = 0; } static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value); static Value construct(Managed *, ExecutionContext *context, Value *, int); static Value call(Managed *, ExecutionContext *, const Value &, Value *, int); @@ -184,6 +181,7 @@ public: protected: static const ManagedVTable static_vtbl; + const ManagedVTable *vtbl; union { diff --git a/src/v4/qv4mm.cpp b/src/v4/qv4mm.cpp index 81dd39a..b81456b 100644 --- a/src/v4/qv4mm.cpp +++ b/src/v4/qv4mm.cpp @@ -229,7 +229,7 @@ std::size_t MemoryManager::sweep(char *chunkStart, std::size_t chunkSize, size_t m->markBit = 0; } else { // qDebug() << "-- collecting it." << m << *f << m->nextFree(); - m->~Managed(); + m->vtbl->destroy(m); m->setNextFree(*f); *f = m; diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp index 0d68f9e..16ce621 100644 --- a/src/v4/qv4object.cpp +++ b/src/v4/qv4object.cpp @@ -82,6 +82,12 @@ Object::~Object() delete [] memberData; delete [] (arrayData - (sparseArray ? 0 : arrayOffset)); delete sparseArray; + _data = 0; +} + +void Object::destroy(Managed *that) +{ + static_cast(that)->~Object(); } void Object::__put__(ExecutionContext *ctx, const QString &name, const Value &value) diff --git a/src/v4/qv4object.h b/src/v4/qv4object.h index 1b29daf..62283bc 100644 --- a/src/v4/qv4object.h +++ b/src/v4/qv4object.h @@ -305,6 +305,7 @@ public: protected: static const ManagedVTable static_vtbl; + static void destroy(Managed *that); static void markObjects(Managed *that); friend struct ObjectIterator; diff --git a/src/v4/qv4regexpobject.cpp b/src/v4/qv4regexpobject.cpp index ccb4d3b..d9abd51 100644 --- a/src/v4/qv4regexpobject.cpp +++ b/src/v4/qv4regexpobject.cpp @@ -63,6 +63,7 @@ using namespace QQmlJS::VM; +DEFINE_MANAGED_VTABLE(RegExpObject); RegExpObject::RegExpObject(ExecutionEngine *engine, PassRefPtr value, bool global) : Object(engine) @@ -85,6 +86,11 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, PassRefPtr value, bo defineReadonlyProperty(engine->newIdentifier(QStringLiteral("multiline")), Value::fromBoolean(this->value->multiLine())); } +void RegExpObject::destroy(Managed *that) +{ + static_cast(that)->~RegExpObject(); +} + PropertyDescriptor *RegExpObject::lastIndexProperty(ExecutionContext *ctx) { assert(0 == internalClass->find(ctx->engine->newIdentifier(QStringLiteral("lastIndex")))); diff --git a/src/v4/qv4regexpobject.h b/src/v4/qv4regexpobject.h index 65df03c..c9cdb80 100644 --- a/src/v4/qv4regexpobject.h +++ b/src/v4/qv4regexpobject.h @@ -69,6 +69,11 @@ struct RegExpObject: Object { PropertyDescriptor *lastIndexProperty(ExecutionContext *ctx); bool global; RegExpObject(ExecutionEngine *engine, PassRefPtr value, bool global); + ~RegExpObject() {} + +protected: + static const ManagedVTable static_vtbl; + static void destroy(Managed *that); }; diff --git a/src/v4/qv4string.cpp b/src/v4/qv4string.cpp index 22b7354..20656ce 100644 --- a/src/v4/qv4string.cpp +++ b/src/v4/qv4string.cpp @@ -73,6 +73,21 @@ static uint toArrayIndex(const QChar *ch, const QChar *end, bool *ok) return i; } +const ManagedVTable String::static_vtbl = +{ + call, + construct, + 0 /*markObjects*/, + destroy, + hasInstance, + "String", +}; + +void String::destroy(Managed *that) +{ + static_cast(that)->~String(); +} + uint String::toUInt(bool *ok) const { *ok = true; diff --git a/src/v4/qv4string.h b/src/v4/qv4string.h index 81566bd..eecaa53 100644 --- a/src/v4/qv4string.h +++ b/src/v4/qv4string.h @@ -61,7 +61,8 @@ struct String : public Managed { String(const QString &text) : _text(text), stringHash(UINT_MAX), identifier(UINT_MAX) - { type = Type_String; subtype = StringType_Unknown; } + { vtbl = &static_vtbl; type = Type_String; subtype = StringType_Unknown; } + ~String() { _data = 0; } inline bool isEqualTo(const String *other) const { if (this == other) @@ -108,6 +109,10 @@ struct String : public Managed { QString _text; mutable uint stringHash; mutable uint identifier; + +protected: + static void destroy(Managed *); + static const ManagedVTable static_vtbl; }; } // namespace VM -- 2.7.4