diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-04-25 22:34:55 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:20:16 +0000 |
commit | 440a25388b55d465873647b3dc9f470ed68e917e (patch) | |
tree | e79cae143659596bcd62b3423699f0cdf2c41fd3 /src/qml/jsruntime | |
parent | a4207b2f958e12b01653d8285d9433a77bce9c52 (diff) |
Make instanceOf compliant with the ES7 spec
Add implementation for Function.prototype[Symbol.hasInstance]
and call it when defined.
Change-Id: Iad6b0c075452b46ba710ffe7b94b74b71f715d22
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 10 |
4 files changed, 27 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index bd32a86691..98db060a00 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -41,6 +41,7 @@ #include "qv4objectproto_p.h" #include "qv4stringobject_p.h" #include "qv4function_p.h" +#include "qv4symbol_p.h" #include <private/qv4mm_p.h> #include "qv4arrayobject_p.h" @@ -277,6 +278,7 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("apply"), method_apply, 2); defineDefaultProperty(QStringLiteral("call"), method_call, 1); defineDefaultProperty(QStringLiteral("bind"), method_bind, 1); + defineDefaultProperty(engine->symbol_hasInstance(), method_hasInstance, 1, Attr_ReadOnly); } ReturnedValue FunctionPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int) @@ -385,6 +387,17 @@ ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Valu return bound->asReturnedValue(); } +ReturnedValue FunctionPrototype::method_hasInstance(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc) +{ + if (!argc) + return false; + const Object *o = thisObject->as<Object>(); + if (!o) + return f->engine()->throwTypeError(); + + return Object::instanceOf(o, argv[0]); +} + DEFINE_OBJECT_VTABLE(ScriptFunction); ReturnedValue ScriptFunction::callAsConstructor(const FunctionObject *fo, const Value *argv, int argc) diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index bd5b756aed..64cd0b96d3 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -205,6 +205,7 @@ struct FunctionPrototype: FunctionObject static ReturnedValue method_apply(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); static ReturnedValue method_bind(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); + static ReturnedValue method_hasInstance(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); }; struct IndexedBuiltinFunction : FunctionObject diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 1237edcdc6..135da55daf 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -61,6 +61,7 @@ #include <private/qqmlengine_p.h> #include <private/qqmljavascriptexpression_p.h> #include "qv4qobjectwrapper_p.h" +#include "qv4symbol_p.h" #include <private/qv8engine_p.h> #endif @@ -361,8 +362,16 @@ QV4::ReturnedValue Runtime::method_instanceof(ExecutionEngine *engine, const Val if (!rhs) return engine->throwTypeError(); - // 11.8.6, 7: call "HasInstance", which we term instanceOf, and return the result. - return rhs->instanceOf(lval); + Scope scope(engine); + ScopedValue hasInstance(scope, rhs->get(engine->symbol_hasInstance())); + if (hasInstance->isUndefined()) + return rhs->instanceOf(lval); + FunctionObject *f = hasInstance->as<FunctionObject>(); + if (!f) + return engine->throwTypeError(); + + ScopedValue result(scope, f->call(&rval, &lval, 1)); + return Encode(result->toBoolean()); } QV4::ReturnedValue Runtime::method_in(ExecutionEngine *engine, const Value &left, const Value &right) diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 4a7339ca3a..1567269932 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -1174,14 +1174,8 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObj MOTH_END_INSTR(CmpIn) MOTH_BEGIN_INSTR(CmpInstanceOf) - // 11.8.6, 5: rval must be an Object - if (Q_UNLIKELY(!Primitive::fromReturnedValue(acc).isObject())) { - acc = engine->throwTypeError(); - goto catchException; - } - - // 11.8.6, 7: call "HasInstance", which we term instanceOf, and return the result. - acc = Primitive::fromReturnedValue(acc).objectValue()->instanceOf(STACK_VALUE(lhs)); + STORE_ACC(); + acc = Runtime::method_instanceof(engine, STACK_VALUE(lhs), ACC); CHECK_EXCEPTION; MOTH_END_INSTR(CmpInstanceOf) |