From 9c1e46ee675969cc4fb1355ff035f67c73dd7b56 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 14 Feb 2013 09:10:30 +0100 Subject: [PATCH] Implement hasInstance through the new 'vtable' Change-Id: I59aea0f64e7ac955c3f1243936d77f2c12103621 Reviewed-by: Simon Hausmann --- src/v4/qmljs_runtime.cpp | 6 +++--- src/v4/qv4argumentsobject.cpp | 15 +++++++-------- src/v4/qv4functionobject.cpp | 36 ++++++++++++++++++++---------------- src/v4/qv4functionobject.h | 5 ++--- src/v4/qv4managed.cpp | 9 ++++++++- src/v4/qv4managed.h | 14 ++++++++++++++ src/v4/qv4object.cpp | 8 ++++++-- 7 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/v4/qmljs_runtime.cpp b/src/v4/qmljs_runtime.cpp index b00d340..77f8b83 100644 --- a/src/v4/qmljs_runtime.cpp +++ b/src/v4/qmljs_runtime.cpp @@ -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); } diff --git a/src/v4/qv4argumentsobject.cpp b/src/v4/qv4argumentsobject.cpp index 16ad93c..f805aa6 100644 --- a/src/v4/qv4argumentsobject.cpp +++ b/src/v4/qv4argumentsobject.cpp @@ -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 -}; - - - } } diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index f904aee..b404ecf 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -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(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 &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(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 -}; diff --git a/src/v4/qv4functionobject.h b/src/v4/qv4functionobject.h index a0eba1a..5cc0aab 100644 --- a/src/v4/qv4functionobject.h +++ b/src/v4/qv4functionobject.h @@ -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 diff --git a/src/v4/qv4managed.cpp b/src/v4/qv4managed.cpp index 411c725..c5935fc 100644 --- a/src/v4/qv4managed.cpp +++ b/src/v4/qv4managed.cpp @@ -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(); +} diff --git a/src/v4/qv4managed.h b/src/v4/qv4managed.h index 00428d5..81c6cb5 100644 --- a/src/v4/qv4managed.h +++ b/src/v4/qv4managed.h @@ -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(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 { diff --git a/src/v4/qv4object.cpp b/src/v4/qv4object.cpp index b174e85..b440cfb 100644 --- a/src/v4/qv4object.cpp +++ b/src/v4/qv4object.cpp @@ -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 }; -- 2.7.4