Get rid of different macros for vtable specializations
authorLars Knoll <lars.knoll@digia.com>
Fri, 4 Apr 2014 10:22:00 +0000 (12:22 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 22 Jul 2014 11:48:54 +0000 (13:48 +0200)
Detect existence of a a vtable entry at compile time.

Change-Id: Ieed5d34b063184bc4435b22c6685ac0e3fabf493
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
28 files changed:
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4arraydata.cpp
src/qml/jsruntime/qv4arrayobject.cpp
src/qml/jsruntime/qv4booleanobject.cpp
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4dateobject.cpp
src/qml/jsruntime/qv4errorobject.cpp
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4globalobject.cpp
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4managed.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4mathobject.cpp
src/qml/jsruntime/qv4memberdata.cpp
src/qml/jsruntime/qv4numberobject.cpp
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4objectiterator.cpp
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4regexp_p.h
src/qml/jsruntime/qv4regexpobject.cpp
src/qml/jsruntime/qv4script.cpp
src/qml/jsruntime/qv4stringobject.cpp
src/qml/qml/qqmlcontextwrapper.cpp
src/qml/qml/qqmlxmlhttprequest.cpp
src/qml/qml/v8/qqmlbuiltinfunctions.cpp
src/qml/types/qqmldelegatemodel.cpp
src/quick/items/context2d/qquickcontext2d.cpp
tools/qmljs/main.cpp

index 9b465a0..9194587 100644 (file)
@@ -44,7 +44,7 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ArgumentsObject);
+DEFINE_OBJECT_VTABLE(ArgumentsObject);
 
 ArgumentsObject::ArgumentsObject(CallContext *context)
     : Object(context->strictMode ? context->engine->strictArgumentsObjectClass : context->engine->argumentsObjectClass)
@@ -197,7 +197,7 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
     return Attr_Accessor;
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ArgumentsGetterFunction);
+DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction);
 
 ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
 {
@@ -212,7 +212,7 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
     return o->context->argument(g->index);
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ArgumentsSetterFunction);
+DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction);
 
 ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
 {
index 0bc97cd..0d68a7c 100644 (file)
@@ -47,7 +47,7 @@ using namespace QV4;
 
 const ArrayVTable SimpleArrayData::static_vtbl =
 {
-    DEFINE_MANAGED_VTABLE_NO_DESTROY_INT(SimpleArrayData),
+    DEFINE_MANAGED_VTABLE_INT(SimpleArrayData),
     SimpleArrayData::Simple,
     SimpleArrayData::reallocate,
     SimpleArrayData::get,
index 95677f2..d5b3b8a 100644 (file)
@@ -46,7 +46,7 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ArrayCtor);
+DEFINE_OBJECT_VTABLE(ArrayCtor);
 
 ArrayCtor::ArrayCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Array"))
index 51931da..662ec64 100644 (file)
@@ -43,8 +43,8 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(BooleanCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(BooleanObject);
+DEFINE_OBJECT_VTABLE(BooleanCtor);
+DEFINE_OBJECT_VTABLE(BooleanObject);
 
 BooleanCtor::BooleanCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Boolean"))
index 899723b..b43b489 100644 (file)
@@ -51,7 +51,7 @@
 
 using namespace QV4;
 
-DEFINE_MANAGED_VTABLE_NO_DESTROY(ExecutionContext);
+DEFINE_MANAGED_VTABLE(ExecutionContext);
 
 CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
 {
index aaa67e9..ceef884 100644 (file)
@@ -641,7 +641,7 @@ static double getLocalTZA()
 #endif
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(DateObject);
+DEFINE_OBJECT_VTABLE(DateObject);
 
 DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
     : Object(engine->dateClass)
@@ -655,7 +655,7 @@ QDateTime DateObject::toQDateTime() const
     return ToDateTime(value.asDouble(), Qt::LocalTime);
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(DateCtor);
+DEFINE_OBJECT_VTABLE(DateCtor);
 
 DateCtor::DateCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Date"))
index 086ca8e..9d6403e 100644 (file)
@@ -249,13 +249,13 @@ URIErrorObject::URIErrorObject(ExecutionEngine *engine, const ValueRef message)
 {
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(EvalErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(RangeErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ReferenceErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(SyntaxErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(TypeErrorCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(URIErrorCtor);
+DEFINE_OBJECT_VTABLE(ErrorCtor);
+DEFINE_OBJECT_VTABLE(EvalErrorCtor);
+DEFINE_OBJECT_VTABLE(RangeErrorCtor);
+DEFINE_OBJECT_VTABLE(ReferenceErrorCtor);
+DEFINE_OBJECT_VTABLE(SyntaxErrorCtor);
+DEFINE_OBJECT_VTABLE(TypeErrorCtor);
+DEFINE_OBJECT_VTABLE(URIErrorCtor);
 
 ErrorCtor::ErrorCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Error"))
index f00df25..04d1afb 100644 (file)
@@ -72,7 +72,7 @@
 using namespace QV4;
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(FunctionObject);
+DEFINE_OBJECT_VTABLE(FunctionObject);
 
 FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
     : Object(scope->engine->functionClass)
@@ -183,7 +183,7 @@ FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Fu
     return new (scope->engine->memoryManager) SimpleScriptFunction(scope, function, createProto);
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(FunctionCtor);
+DEFINE_OBJECT_VTABLE(FunctionCtor);
 
 FunctionCtor::FunctionCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Function"))
@@ -353,7 +353,7 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
     return ctx->engine->newBoundFunction(ctx->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ScriptFunction);
+DEFINE_OBJECT_VTABLE(ScriptFunction);
 
 ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
     : SimpleScriptFunction(scope, function, true)
@@ -426,7 +426,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
     return result.asReturnedValue();
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(SimpleScriptFunction);
+DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
 
 SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *function, bool createProto)
     : FunctionObject(scope, function->name(), createProto)
@@ -550,7 +550,7 @@ InternalClass *SimpleScriptFunction::internalClassForConstructor()
 
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(BuiltinFunction);
+DEFINE_OBJECT_VTABLE(BuiltinFunction);
 
 BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *))
     : FunctionObject(scope, name)
@@ -602,7 +602,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
     return f->code(&ctx, f->index);
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(IndexedBuiltinFunction);
+DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
 
 DEFINE_OBJECT_VTABLE(BoundFunction);
 
index feac21a..eb0994c 100644 (file)
@@ -344,7 +344,7 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
     return QString();
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(EvalFunction);
+DEFINE_OBJECT_VTABLE(EvalFunction);
 
 EvalFunction::EvalFunction(ExecutionContext *scope)
     : FunctionObject(scope, scope->engine->id_eval)
index 556b2ea..ca82af1 100644 (file)
@@ -66,7 +66,7 @@ static int indent = 0;
 #endif
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(JsonObject);
+DEFINE_OBJECT_VTABLE(JsonObject);
 
 class JsonParser
 {
index 3cfbb37..69022df 100644 (file)
@@ -45,6 +45,7 @@
 
 using namespace QV4;
 
+
 const ManagedVTable Managed::static_vtbl =
 {
     Managed::IsExecutionContext,
index 1718149..93a50e2 100644 (file)
@@ -82,6 +82,10 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
     public: \
         enum { MyType = Type_##type };
 
+#define Q_VTABLE_FUNCTION(classname, func) \
+    (classname::func == QV4::Managed::func ? 0 : classname::func)
+
+
 struct GCDeletable
 {
     GCDeletable() : next(0), lastCall(false) {}
@@ -125,23 +129,8 @@ struct ObjectVTable
     void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
 };
 
-#define DEFINE_MANAGED_VTABLE_INT(classname) \
-{     \
-    classname::IsExecutionContext,   \
-    classname::IsString,   \
-    classname::IsObject,   \
-    classname::IsFunctionObject,   \
-    classname::IsErrorObject,   \
-    classname::IsArrayData,   \
-    0,                                          \
-    classname::MyType,                          \
-    #classname,                                 \
-    destroy,                                    \
-    markObjects,                                \
-    isEqualTo                                  \
-}
 
-#define DEFINE_MANAGED_VTABLE_NO_DESTROY_INT(classname) \
+#define DEFINE_MANAGED_VTABLE_INT(classname) \
 {     \
     classname::IsExecutionContext,   \
     classname::IsString,   \
@@ -152,15 +141,13 @@ struct ObjectVTable
     0,                                          \
     classname::MyType,                          \
     #classname,                                 \
-    0,                                    \
+    Q_VTABLE_FUNCTION(classname, destroy),                                    \
     markObjects,                                \
     isEqualTo                                  \
 }
 
 #define DEFINE_MANAGED_VTABLE(classname) \
 const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
-#define DEFINE_MANAGED_VTABLE_NO_DESTROY(classname) \
-const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_NO_DESTROY_INT(classname)
 
 
 #define DEFINE_OBJECT_VTABLE(classname) \
@@ -183,47 +170,6 @@ const QV4::ObjectVTable classname::static_vtbl =    \
     advanceIterator                            \
 }
 
-#define DEFINE_OBJECT_VTABLE_NO_DESTROY(classname) \
-const QV4::ObjectVTable classname::static_vtbl =    \
-{     \
-    DEFINE_MANAGED_VTABLE_NO_DESTROY_INT(classname), \
-    call,                                       \
-    construct,                                  \
-    get,                                        \
-    getIndexed,                                 \
-    put,                                        \
-    putIndexed,                                 \
-    query,                                      \
-    queryIndexed,                               \
-    deleteProperty,                             \
-    deleteIndexedProperty,                      \
-    getLookup,                                  \
-    setLookup,                                  \
-    getLength,                                  \
-    advanceIterator                            \
-}
-
-#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
-const QV4::ObjectVTable classname::static_vtbl =    \
-{                                               \
-    DEFINE_MANAGED_VTABLE_INT(name), \
-    call,                                       \
-    construct,                                  \
-    get,                                        \
-    getIndexed,                                 \
-    put,                                        \
-    putIndexed,                                 \
-    query,                                      \
-    queryIndexed,                               \
-    deleteProperty,                             \
-    deleteIndexedProperty,                      \
-    getLookup,                                  \
-    setLookup,                                  \
-    getLength,                                  \
-    advanceIterator                            \
-}
-
-
 struct Q_QML_PRIVATE_EXPORT Managed
 {
     V4_MANAGED
@@ -359,6 +305,7 @@ public:
             uchar _flags;
         };
     };
+    static void destroy(Managed *) {}
 
 private:
     friend class MemoryManager;
index 66fb06d..16d76e6 100644 (file)
@@ -51,7 +51,7 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(MathObject);
+DEFINE_OBJECT_VTABLE(MathObject);
 
 static const double qt_PI = 2.0 * ::asin(1.0);
 
index 7c3b2b9..005e296 100644 (file)
@@ -44,7 +44,7 @@
 
 using namespace QV4;
 
-DEFINE_MANAGED_VTABLE_NO_DESTROY(MemberData);
+DEFINE_MANAGED_VTABLE(MemberData);
 
 void MemberData::markObjects(Managed *that, ExecutionEngine *e)
 {
index 16f81bc..c97e86f 100644 (file)
@@ -48,8 +48,8 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(NumberCtor);
-DEFINE_OBJECT_VTABLE_NO_DESTROY(NumberObject);
+DEFINE_OBJECT_VTABLE(NumberCtor);
+DEFINE_OBJECT_VTABLE(NumberObject);
 
 NumberCtor::NumberCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Number"))
index c67ca6a..11f8202 100644 (file)
@@ -68,7 +68,7 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(Object);
+DEFINE_OBJECT_VTABLE(Object);
 
 Object::Object(ExecutionEngine *engine)
     : Managed(engine->objectClass)
@@ -1152,7 +1152,7 @@ void Object::initSparseArray()
 }
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ArrayObject);
+DEFINE_OBJECT_VTABLE(ArrayObject);
 
 ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
     : Object(engine->arrayClass)
index f9ad00e..e5f693c 100644 (file)
@@ -192,7 +192,7 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
 }
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ForEachIteratorObject);
+DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
 
 void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
 {
index 4d54a99..5c824bd 100644 (file)
@@ -72,7 +72,7 @@
 using namespace QV4;
 
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(ObjectCtor);
+DEFINE_OBJECT_VTABLE(ObjectCtor);
 
 ObjectCtor::ObjectCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("Object"))
index 1bcc2c6..63d4ed3 100644 (file)
@@ -109,7 +109,6 @@ public:
     bool multiLine() const { return m_multiLine; }
     int captureCount() const { return m_subPatternCount + 1; }
 
-protected:
     static void destroy(Managed *that);
     static void markObjects(Managed *that, QV4::ExecutionEngine *e);
 
index a173dbc..7a7666b 100644 (file)
@@ -69,7 +69,7 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyn
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(RegExpObject);
+DEFINE_OBJECT_VTABLE(RegExpObject);
 
 RegExpObject::RegExpObject(InternalClass *ic)
     : Object(ic)
@@ -226,7 +226,7 @@ uint RegExpObject::flags() const
     return f;
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(RegExpCtor);
+DEFINE_OBJECT_VTABLE(RegExpCtor);
 
 RegExpCtor::RegExpCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("RegExp"))
index e3fc156..36f61a1 100644 (file)
@@ -164,7 +164,7 @@ Returned<FunctionObject> *QmlBindingWrapper::createQmlCallableForFunction(QQmlCo
     return function->asReturned<FunctionObject>();
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QmlBindingWrapper);
+DEFINE_OBJECT_VTABLE(QmlBindingWrapper);
 
 struct CompilationUnitHolder : public QV4::Object
 {
index 5385a76..f1e5170 100644 (file)
@@ -75,7 +75,7 @@
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(StringObject);
+DEFINE_OBJECT_VTABLE(StringObject);
 
 StringObject::StringObject(InternalClass *ic)
     : Object(ic)
@@ -171,7 +171,7 @@ void StringObject::markObjects(Managed *that, ExecutionEngine *e)
     Object::markObjects(that, e);
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(StringCtor);
+DEFINE_OBJECT_VTABLE(StringCtor);
 
 StringCtor::StringCtor(ExecutionContext *scope)
     : FunctionObject(scope, QStringLiteral("String"))
index 1480625..a5574b7 100644 (file)
@@ -437,7 +437,7 @@ ReturnedValue QmlContextWrapper::qmlSingletonWrapper(QV8Engine *v8, const String
     return QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine());
 }
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQmlIdObjectsArray);
+DEFINE_OBJECT_VTABLE(QQmlIdObjectsArray);
 
 QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper)
     : Object(engine)
index 1a8564d..d89dc92 100644 (file)
@@ -302,7 +302,7 @@ public:
 
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(NodePrototype);
+DEFINE_OBJECT_VTABLE(NodePrototype);
 
 class Node : public Object
 {
@@ -1696,7 +1696,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
     Object *proto;
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQmlXMLHttpRequestCtor);
+DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestCtor);
 
 void QQmlXMLHttpRequestCtor::setupProto()
 {
index 03e2830..67e9e80 100644 (file)
@@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE
 
 using namespace QV4;
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QtObject);
+DEFINE_OBJECT_VTABLE(QtObject);
 
 struct StaticQtMetaObject : public QObject
 {
index c86f1c9..f7ce1c8 100644 (file)
@@ -93,7 +93,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
     }
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(DelegateModelGroupFunction);
+DEFINE_OBJECT_VTABLE(DelegateModelGroupFunction);
 
 
 
@@ -3237,7 +3237,7 @@ struct QQmlDelegateModelGroupChange : QV4::Object
     QQmlChangeSet::Change change;
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQmlDelegateModelGroupChange);
+DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChange);
 
 class QQmlDelegateModelGroupChangeArray : public QV4::Object
 {
index 3ba84b5..9b78b9e 100644 (file)
@@ -531,7 +531,7 @@ public:
 protected:
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQuickJSContext2D);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
 
 
 struct QQuickJSContext2DPrototype : public QV4::Object
@@ -637,7 +637,7 @@ public:
 
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQuickJSContext2DPrototype);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2DPrototype);
 
 
 class QQuickContext2DStyle : public QV4::Object
@@ -919,7 +919,7 @@ struct QQuickJSContext2DImageData : public QV4::Object
 
 DEFINE_REF(QQuickJSContext2DImageData, QV4::Object);
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(QQuickJSContext2DImageData);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData);
 
 static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV8Engine* engine, const QImage& image)
 {
index 26376fa..aaddfbf 100644 (file)
@@ -90,7 +90,7 @@ struct Print: FunctionObject
     }
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(Print);
+DEFINE_OBJECT_VTABLE(Print);
 
 struct GC: public FunctionObject
 {
@@ -107,7 +107,7 @@ struct GC: public FunctionObject
     }
 };
 
-DEFINE_OBJECT_VTABLE_NO_DESTROY(GC);
+DEFINE_OBJECT_VTABLE(GC);
 
 } // builtins