Implement hasInstance through the new 'vtable'
authorLars Knoll <lars.knoll@digia.com>
Thu, 14 Feb 2013 08:10:30 +0000 (09:10 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 14 Feb 2013 10:57:33 +0000 (11:57 +0100)
Change-Id: I59aea0f64e7ac955c3f1243936d77f2c12103621
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/v4/qmljs_runtime.cpp
src/v4/qv4argumentsobject.cpp
src/v4/qv4functionobject.cpp
src/v4/qv4functionobject.h
src/v4/qv4managed.cpp
src/v4/qv4managed.h
src/v4/qv4object.cpp

index b00d340..77f8b83 100644 (file)
@@ -236,11 +236,11 @@ void __qmljs_add_helper(ExecutionContext *ctx, Value *result, const Value *left,
 
 void __qmljs_instanceof(ExecutionContext *ctx, Value *result, const Value *left, const Value *right)
 {
-    FunctionObject *function = right->asFunctionObject();
-    if (!function)
+    Object *o = right->asObject();
+    if (!o)
         __qmljs_throw_type_error(ctx);
 
-    bool r = function->hasInstance(ctx, *left);
+    bool r = o->hasInstance(ctx, left);
     *result = Value::fromBoolean(r);
 }
 
index 16ad93c..f805aa6 100644 (file)
@@ -50,6 +50,13 @@ static Value throwTypeError(ExecutionContext *ctx)
     return Value::undefinedValue();
 }
 
+const ManagedVTable ArgumentsObject::static_vtbl =
+{
+    ArgumentsObject::markObjects,
+    Managed::hasInstance,
+    ManagedVTable::EndOfVTable
+};
+
 ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterCount, int actualParameterCount)
     : Object(context->engine), context(context)
 {
@@ -164,13 +171,5 @@ void ArgumentsObject::markObjects(Managed *that)
     Object::markObjects(that);
 }
 
-
-const ManagedVTable ArgumentsObject::static_vtbl =
-{
-    ArgumentsObject::markObjects
-};
-
-
-
 }
 }
index f904aee..b404ecf 100644 (file)
@@ -103,24 +103,24 @@ FunctionObject::FunctionObject(ExecutionContext *scope)
     strictMode = false;
 }
 
-bool FunctionObject::hasInstance(ExecutionContext *ctx, const Value &value)
+bool FunctionObject::hasInstance(Managed *that, ExecutionContext *ctx, const Value *value)
 {
-    if (! value.isObject())
+    FunctionObject *f = static_cast<FunctionObject *>(that);
+
+    Object *v = value->asObject();
+    if (!v)
         return false;
 
-    Value o = __get__(ctx, ctx->engine->id_prototype);
-    if (! o.isObject()) {
+    Object *o = f->__get__(ctx, ctx->engine->id_prototype).asObject();
+    if (!o)
         ctx->throwTypeError();
-        return false;
-    }
 
-    Object *v = value.objectValue();
     while (v) {
         v = v->prototype;
 
         if (! v)
             break;
-        else if (o.objectValue() == v)
+        else if (o == v)
             return true;
     }
 
@@ -209,7 +209,9 @@ Value FunctionObject::construct(ExecutionContext *ctx)
 
 const ManagedVTable FunctionObject::static_vtbl =
 {
-    FunctionObject::markObjects
+    FunctionObject::markObjects,
+    FunctionObject::hasInstance,
+    ManagedVTable::EndOfVTable
 };
 
 
@@ -438,6 +440,12 @@ Value BuiltinFunction::construct(ExecutionContext *ctx)
     return Value::undefinedValue();
 }
 
+const ManagedVTable BoundFunction::static_vtbl =
+{
+    BoundFunction::markObjects,
+    BoundFunction::hasInstance,
+    ManagedVTable::EndOfVTable
+};
 
 BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs)
     : FunctionObject(scope)
@@ -478,9 +486,10 @@ Value BoundFunction::construct(ExecutionContext *context, Value *args, int argc)
     return target->construct(context, newArgs, boundArgs.size() + argc);
 }
 
-bool BoundFunction::hasInstance(ExecutionContext *ctx, const Value &value)
+bool BoundFunction::hasInstance(Managed *that, ExecutionContext *ctx, const Value *value)
 {
-    return target->hasInstance(ctx, value);
+    BoundFunction *f = static_cast<BoundFunction *>(that);
+    return FunctionObject::hasInstance(f->target, ctx, value);
 }
 
 void BoundFunction::markObjects(Managed *that)
@@ -494,8 +503,3 @@ void BoundFunction::markObjects(Managed *that)
             m->mark();
     FunctionObject::markObjects(that);
 }
-
-const ManagedVTable BoundFunction::static_vtbl =
-{
-    BoundFunction::markObjects
-};
index a0eba1a..5cc0aab 100644 (file)
@@ -156,8 +156,6 @@ struct Q_V4_EXPORT FunctionObject: Object {
 
     FunctionObject(ExecutionContext *scope);
 
-    virtual bool hasInstance(ExecutionContext *ctx, const Value &value);
-
     virtual Value construct(ExecutionContext *context, Value *args, int argc);
     virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
 
@@ -169,6 +167,7 @@ protected:
 
     static const ManagedVTable static_vtbl;
     static void markObjects(Managed *that);
+    static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value *value);
 };
 
 struct FunctionCtor: FunctionObject
@@ -227,10 +226,10 @@ struct BoundFunction: FunctionObject {
 
     virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
     virtual Value construct(ExecutionContext *context, Value *args, int argc);
-    virtual bool hasInstance(ExecutionContext *ctx, const Value &value);
 
     static const ManagedVTable static_vtbl;
     static void markObjects(Managed *that);
+    static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value *value);
 };
 
 } // namespace VM
index 411c725..c5935fc 100644 (file)
@@ -47,7 +47,9 @@ using namespace QQmlJS::VM;
 
 const ManagedVTable Managed::static_vtbl =
 {
-    0 // markObjects
+    0 /*markObjects*/,
+    Managed::hasInstance,
+    ManagedVTable::EndOfVTable
 };
 
 
@@ -144,3 +146,8 @@ QString Managed::className() const
     }
     return QString::fromLatin1(s);
 }
+
+bool Managed::hasInstance(Managed *, ExecutionContext *ctx, const Value *)
+{
+    ctx->throwTypeError();
+}
index 00428d5..81c6cb5 100644 (file)
@@ -72,10 +72,17 @@ struct ArgumentsObject;
 struct JSONObject;
 struct ForeachIteratorObject;
 struct Managed;
+struct Value;
+
 
 struct ManagedVTable
 {
+    enum _EndOfVTable {
+        EndOfVTable
+    };
     void (*markObjects)(Managed *);
+    bool (*hasInstance)(Managed *, ExecutionContext *ctx, const Value *value);
+    _EndOfVTable endofVTable;
 };
 
 struct Q_V4_EXPORT Managed
@@ -150,10 +157,17 @@ public:
         *reinterpret_cast<Managed **>(this) = m;
     }
 
+    inline bool hasInstance(ExecutionContext *ctx, const Value *v) {
+        return vtbl->hasInstance(this, ctx, v);
+    }
+
+    static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value *value);
+
 protected:
 
     static const ManagedVTable static_vtbl;
     const ManagedVTable *vtbl;
+
     union {
         uint _data;
         struct {
index b174e85..b440cfb 100644 (file)
@@ -987,7 +987,9 @@ void Object::markArrayObjects() const
 
 const ManagedVTable Object::static_vtbl =
 {
-    Object::markObjects
+    Object::markObjects,
+    Managed::hasInstance,
+    ManagedVTable::EndOfVTable
 };
 
 void ArrayObject::init(ExecutionContext *context)
@@ -1015,5 +1017,7 @@ void ForEachIteratorObject::markObjects(Managed *that)
 
 const ManagedVTable ForEachIteratorObject::static_vtbl =
 {
-    ForEachIteratorObject::markObjects
+    ForEachIteratorObject::markObjects,
+    Managed::hasInstance,
+    ManagedVTable::EndOfVTable
 };