aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-25 22:34:55 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:20:16 +0000
commit440a25388b55d465873647b3dc9f470ed68e917e (patch)
treee79cae143659596bcd62b3423699f0cdf2c41fd3 /src/qml/jsruntime
parenta4207b2f958e12b01653d8285d9433a77bce9c52 (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.cpp13
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp13
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp10
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)