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>
This commit is contained in:
parent
a4207b2f95
commit
440a25388b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -583,16 +583,10 @@ built-ins/Function/length/S15.3.5.1_A2_T1.js fails
|
|||
built-ins/Function/length/S15.3.5.1_A2_T2.js fails
|
||||
built-ins/Function/length/S15.3.5.1_A2_T3.js fails
|
||||
built-ins/Function/proto-from-ctor-realm.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/length.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/name.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/prop-desc.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/this-val-bound-target.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/this-val-not-callable.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/this-val-poisoned-prototype.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/value-get-prototype-of-err.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/value-negative.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/value-non-obj.js fails
|
||||
built-ins/Function/prototype/Symbol.hasInstance/value-positive.js fails
|
||||
built-ins/Function/prototype/bind/BoundFunction_restricted-properties.js fails
|
||||
built-ins/Function/prototype/bind/get-fn-realm.js fails
|
||||
built-ins/Function/prototype/bind/instance-construct-newtarget-boundtarget-bound.js fails
|
||||
|
@ -4795,9 +4789,6 @@ language/expressions/generators/yield-spread-arr-single.js fails
|
|||
language/expressions/generators/yield-star-before-newline.js fails
|
||||
language/expressions/instanceof/prototype-getter-with-object-throws.js fails
|
||||
language/expressions/instanceof/prototype-getter-with-object.js fails
|
||||
language/expressions/instanceof/symbol-hasinstance-get-err.js fails
|
||||
language/expressions/instanceof/symbol-hasinstance-invocation.js fails
|
||||
language/expressions/instanceof/symbol-hasinstance-to-boolean.js fails
|
||||
language/expressions/logical-and/tco-right.js strictFails
|
||||
language/expressions/logical-or/tco-right.js strictFails
|
||||
language/expressions/new.target/asi.js fails
|
||||
|
|
Loading…
Reference in New Issue